2011-11-03 38 views
0

我有一个线程在我的Swing聊天应用程序中运行,无限期地通过套接字来侦听数据报。当我关闭这个应用程序,我有以下代码执行:使用Thread.interrupt在Java中杀死一个线程

listenThread.interrupt(); 
socket.close(); 

然而,中断似乎没有要停止线程,当插座关闭,循环将继续倾听,而且由于插座引发异常已经被关了。如何让线程正常退出以便我可以安全地关闭套接字?

+0

你可以发布你用来监听连接的代码吗?是这样的:while(running){sock = sSock.accept(); ...}? –

+1

* interrupt()*不能用于中断I/O操作,例如套接字读取或写入。要中止I/O,关闭套接字是正确的方法。在线程收到IOException后,它应该检查它是否被[中断](http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#isInterrupted%28%29)在此期间,然后优雅地退出。 – JimmyB

+0

@HannoBinder,你应该把它放在你的答案中。关于为什么你的代码是正确的,这是一个相当不错的解释。 –

回答

4

interrupt()不能用于中断I/O操作,例如套接字读取或写入。要中止I/O,关闭套接字是正确的方法。在线索收到IOException之后,它应该检查它是否在此期间中断,然后正常退出。

实例为您的I/O线程的代码:

while(!Thread.currentThread().isInterrupted()) { 
    try { 
    doRead(); 
    } catch (IOException ioe) { 
    // Log exception or whatever 
    } 
} 
+0

其实这不适用于NIO。 – Voo

0

interrupt()只通知该线程有人有意停止它。这取决于线程正确退出。如果线程在显示器上等待,它将收到InterruptedException,否则您可以在当前线程上检查isInterrupted()。但是,如果它在IO上等待,您可能会运气不佳,而您唯一的选择是等待套接字超时过期。然后你会检查线程是否中断并关闭了套接字。

0

如果它抛出一个异常,捕获它并退出UDP读线程。当套接字从另一个线程关闭时抛出异常 - 使用它!

如果不成功,请设置中断标志,并通过从请求关闭的线程中的套接字向本地TCP堆栈发送一个数据报以使UDP读取()返回。 UDP是一种无连接的消息服务,并且非常乐意从同一个盒子上的另一个线程接收数据报。数据报可以包含一个关闭指令,或者你可以在每次read()返回后检查isInterrupted标志,以防万一它被设置。

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 
+0

虽然我不希望我的套接字超时,但我希望它能够中继消息,无论它闲置多久。 –

+0

您可以让它超时,检查退出,然后退出/继续监听,或者您可以关闭套接字并抛出IOException。我很确定没有办法做到这一点。 – VolatileDream

+0

套接字不会侦听的时间会很少,并且不会导致应用程序出现问题。 – VolatileDream