毫无疑问,这个问题在过去曾以各种形式提出,但对于具体情况而言并非如此。
在等待通过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)
使用一些在中断方法中被翻转的状态。这是最好的方法吗?还是有更优雅的方式?
由于
答案 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, 马丁