使用Thread.interrupt在Java中杀死一个线程

时间:2011-11-03 19:36:22

标签: java multithreading sockets

我在Swing聊天应用程序中运行了一个线程,无限期地通过套接字监听数据报。当我关闭此应用程序时,我执行以下代码:

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

但是,中断似乎没有停止线程,因为当套接字关闭时,循环继续侦听,并且因为套接字已关闭而抛出异常。如何让线程正确退出以便我可以安全地关闭套接字?

4 个答案:

答案 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