我在Swing聊天应用程序中运行了一个线程,无限期地通过套接字监听数据报。当我关闭此应用程序时,我执行以下代码:
listenThread.interrupt();
socket.close();
但是,中断似乎没有停止线程,因为当套接字关闭时,循环继续侦听,并且因为套接字已关闭而抛出异常。如何让线程正确退出以便我可以安全地关闭套接字?
答案 0 :(得分:4)
interrupt()
不能用于中断I / O操作,例如套接字读取或写入。要中止I / O,关闭套接字是正确的方法。在您的线程收到IOException
之后,它应检查它是否在此期间被中断,然后正常退出。
I / O线程中的代码示例:
while( !Thread.currentThread().isInterrupted() ) {
try {
doRead();
} catch ( IOException ioe ) {
// Log exception or whatever
}
}
答案 1 :(得分:0)
interrupt()
仅通知线程某人有意阻止它。这取决于正确退出的线程。如果线程在监视器上等待它将收到InterruptedException
,否则您可以检查当前线程上的isInterrupted()
。但是,如果它在IO上等待你可能会运气不好,你唯一的选择就是等待套接字超时到期。然后你将检查线程是否被中断并关闭套接字。
答案 2 :(得分:0)
如果它抛出异常,请捕获它并退出UDP读取线程。预期从另一个线程关闭套接字时抛出异常 - 使用它!
如果失败,设置中断标志并通过从请求关闭的线程中的套接字向本地TCP堆栈发送数据报来使UDP read()返回。 UDP是一种无连接的消息服务,非常乐意从同一个盒子上的另一个线程接收数据报。数据报可以包含一个关闭指令,或者你可以在每次read()返回后检查isInterrupted标志,以防它被设置。
答案 3 :(得分:0)
我将假设您已经通过简单的方式实现了这一点:
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