繁体   English   中英

使用Thread.interrupt杀死Java中的线程

[英]Killing a thread in Java using Thread.interrupt

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

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
  }
}

interrupt()仅通知线程某人打算停止它的意图。 取决于线程是否正确退出。 如果线程在监视器上等待,它将收到InterruptedException ,否则可以在当前线程上检查isInterrupted() 但是,如果它正在等待IO,那么您可能不走运,您唯一的选择是等待套接字超时到期。 然后,您将检查线程是否中断并关闭套接字。

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

失败的话,设置中断标志并通过从请求关闭的线程中的套接字向本地TCP堆栈发送数据报来使UDP read()返回。 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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM