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

时间:2011-08-20 14:12:58

标签: java multithreading networking interrupt-handling

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

在等待通过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(),然后在run的catch中的SocketException方法中为它提供服务。 。或者也许代替while(true)使用一些在中断方法中被翻转的状态。这是最好的方法吗?还是有更优雅的方式?

由于

4 个答案:

答案 0 :(得分:4)

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

  

当前在receive(java.net.DatagramPacket)中阻止的任何线程   这个套接字会抛出一个SocketException

您也可以使用setSoTimeout仅在很短的时间内制作接收方法块。方法返回后,您的线程可以检查它是否已被中断,并在这么短的时间内重试再次接收。

答案 1 :(得分:3)

答案 2 :(得分:2)

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

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

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

另外,如果你想避免在一些IO状态下阻塞你的线程,等待套接字,你应该给你的套接字连接并读取超时(方法setSoTimeout)。

此致  斯特凡

答案 3 :(得分:0)

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

RGDS, 马丁