我有一个线程在我的Swing聊天应用程序中运行,无限期地通过套接字来侦听数据报。当我关闭这个应用程序,我有以下代码执行:使用Thread.interrupt在Java中杀死一个线程
listenThread.interrupt();
socket.close();
然而,中断似乎没有要停止线程,当插座关闭,循环将继续倾听,而且由于插座引发异常已经被关了。如何让线程正常退出以便我可以安全地关闭套接字?
我有一个线程在我的Swing聊天应用程序中运行,无限期地通过套接字来侦听数据报。当我关闭这个应用程序,我有以下代码执行:使用Thread.interrupt在Java中杀死一个线程
listenThread.interrupt();
socket.close();
然而,中断似乎没有要停止线程,当插座关闭,循环将继续倾听,而且由于插座引发异常已经被关了。如何让线程正常退出以便我可以安全地关闭套接字?
interrupt()
不能用于中断I/O操作,例如套接字读取或写入。要中止I/O,关闭套接字是正确的方法。在线索收到IOException
之后,它应该检查它是否在此期间中断,然后正常退出。
实例为您的I/O线程的代码:
while(!Thread.currentThread().isInterrupted()) {
try {
doRead();
} catch (IOException ioe) {
// Log exception or whatever
}
}
其实这不适用于NIO。 – Voo
interrupt()
只通知该线程有人有意停止它。这取决于线程正确退出。如果线程在显示器上等待,它将收到InterruptedException
,否则您可以在当前线程上检查isInterrupted()
。但是,如果它在IO上等待,您可能会运气不佳,而您唯一的选择是等待套接字超时过期。然后你会检查线程是否中断并关闭了套接字。
如果它抛出一个异常,捕获它并退出UDP读线程。当套接字从另一个线程关闭时抛出异常 - 使用它!
如果不成功,请设置中断标志,并通过从请求关闭的线程中的套接字向本地TCP堆栈发送一个数据报以使UDP读取()返回。 UDP是一种无连接的消息服务,并且非常乐意从同一个盒子上的另一个线程接收数据报。数据报可以包含一个关闭指令,或者你可以在每次read()返回后检查isInterrupted标志,以防万一它被设置。
我会假设你已经这样实施了简单的方法,做:
DatagramSocket s = new DatagramSocket(port);
DatagramPacket p = new DatagramPacket(new byte[256], 256);
s.receive(p);
现在,看的Javadoc,有没有办法让DatagramSocket.receive()
抛出一个InterruptedException。关闭套接字是让它停止收听的唯一方法。
一个更好的实现方式是使用DatagramSocket.setSoTimeout(int)
将DatagramSocket设置为2秒钟之类的小事,然后检查您的服务器是否被中断。所以你最终会得到类似于你的服务器代码的东西(不处理异常):
DatagramSocket s = new DatagramSocket(port);
s.setSoTimeout(2000); // 2 second time out
while(running){ // boolean running flag, check for interrupt here
try{
DatagramPacket p = new DatagramPacket(new byte[256], 256);
s.receive(p);
//do stuff
} catch (SocketTimeoutException e){
//timed out
}
}//end while
虽然我不希望我的套接字超时,但我希望它能够中继消息,无论它闲置多久。 –
您可以让它超时,检查退出,然后退出/继续监听,或者您可以关闭套接字并抛出IOException。我很确定没有办法做到这一点。 – VolatileDream
套接字不会侦听的时间会很少,并且不会导致应用程序出现问题。 – VolatileDream
你可以发布你用来监听连接的代码吗?是这样的:while(running){sock = sSock.accept(); ...}? –
* interrupt()*不能用于中断I/O操作,例如套接字读取或写入。要中止I/O,关闭套接字是正确的方法。在线程收到IOException后,它应该检查它是否被[中断](http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#isInterrupted%28%29)在此期间,然后优雅地退出。 – JimmyB
@HannoBinder,你应该把它放在你的答案中。关于为什么你的代码是正确的,这是一个相当不错的解释。 –