繁体   English   中英

停止线程等待网络活动的正确方法是什么?

[英]What is the correct way to stop a thread waiting for network activity?

毫无疑问,这个问题在过去曾以各种形式提出过,但对于具体情况而言并非如此。

在等待通过UDP接收网络消息时阻止阻塞的线程的最正确方法是什么。

例如,假设我有以下线程:

public class ClientDiscoveryEngine extends Thread {

    private final int PORT;

    public ClientDiscoveryEngine(final int portNumber) {
        PORT = portNumber;
    }

    @Override
    public void run() {
        try {
            socket = new DatagramSocket(RECEIVE_PORT);

            while (true) {
                final byte[] data = new byte[256];
                final DatagramPacket packet = new DatagramPacket(data, data.length);

                socket.receive(packet);
            }
        } catch (SocketException e) {
            // do stuff 1
        } catch (IOException e) {
            // do stuff 2
        }
    }
}

现在,更正确的方法是使用interrupt()方法吗? 例如,添加以下方法:

@Override
public void interrupt() {
    super.interrupt();
    // flip some state?
}

我唯一关心的是, socket.receive()不是一个不可中断的阻塞方法吗? 我想到的一种方法是实现上面的中断方法,在该方法中调用socket.close()然后在catch的SocketException中的run方法中为它提供服务。 或者也许代替while(true)使用一些在中断方法中被翻转的状态。 这是最好的方法吗? 还是有更优雅的方式?

谢谢

接收方法似乎不可中断。 你可以关闭套接字:javadoc说:

此套接字上当前在receive(java.net.DatagramPacket)被阻塞的任何线程都将抛出SocketException

您还可以使用setSoTimeout仅在少量时间内创建接收方法块。 方法返回后,您的线程可以检查它是否已被中断,并在这么短的时间内重新尝试再次接收。

要停止一个线程,你不应该在java中既不中断也不停止。 正如您在问题结束时所建议的那样,最好的方法是让主方法内的循环由一个标志控制,您可以根据需要升级。

这是一个关于此的旧链接: http//download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

其他停止线程的方法已被弃用,并且不提供与此相同的控制权。 此外,这可能与执行者服务有所改变,我没有时间去了解它。

此外,如果要避免在某些IO状态下阻塞线程,等待套接字,则应该为套接字提供连接并读取超时(方法setSoTimeout )。

此致,Stéphane

这是比较容易的一个。 如果它在UDP套接字上被阻止,则向套接字发送一条UDP消息,指示接收线程“停止”。

Rgds,马丁

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM