繁体   English   中英

调用interrupt()时,线程未引发InterruptedException

[英]Thread not throwing an InterruptedException when interrupt() is called

我正在开发一个通过网络读取和处理数据的应用程序。 在测试程序的连接/断开逻辑时,我注意到我的使用者线程在达到关闭状态时并未关闭。 下面是消费者类的精简版。

import java.io.InputStream;

public class Consumer implements Runnable
{
   private final InputStream input;
   public Consumer(InputStream input)
   {
      this.input = input;
   }
   @Override
   public void run()
   {      
      byte readBuffer[];
      readBuffer = new byte[1];
      int goodData;

      try
      {
         while(input.available() > 0)
         {
            goodData = input.read(readBuffer);
            while (goodData > 0 )
            {
               System.out.println(readBuffer[0]);
               if ( readBuffer[0] == 27 )
               {
                  System.out.println("Consumer: found closing byte and closing thread "+Thread.currentThread().getName());
                  //this is the last packet, so interupt thread to close
              Thread.currentThread().interrupt();
              //return;
              //Thread.currentThread().stop(new InterruptedException("Attempting to close"));
               }
               goodData = input.read(readBuffer);
            }
         }
      }
      catch(Exception e)
      {
         System.out.println("closing "+Thread.currentThread().getName() +" because of an exception "+e.getClass());
         return;
      }
      System.out.println("closing "+Thread.currentThread().getName());
   }
}

我创建了一个虚拟的主类来演示该问题。

public class ExampleOfInterruptNotWorking
{
   public static void main(String[] args)
   {
      byte[] bytesToWrite = new byte[]{0, 1, 2,3,4,5,6,65,23,65,21,54,13,54,1,76};
      Consumer C;
      Thread ConsumerThread;
      PipedInputStream PIS = null;
      PipedOutputStream POS = null;
      try
      {
         PIS = new PipedInputStream();
         POS = new PipedOutputStream(PIS);
         C = new Consumer(PIS);
         ConsumerThread = new Thread(C);

         ConsumerThread.start();

         POS.write(bytesToWrite);
         POS.write(bytesToWrite);
         bytesToWrite[1] = 27;
         POS.write(bytesToWrite);

         ConsumerThread.join();

      }
      catch(Exception e)
      {
         System.err.println("Unexpected exception in main");
         e.printStackTrace(System.err);
      }
      finally
      {
         try
         {
            PIS.close();
            POS.close();
         }
         catch(Exception ex)
         {
        //shouldn't happen in example
         }
         System.out.println("exiting main");
      }
   }
}

当您按编写的方式运行此代码时,使用者将检测到中断,但是直到管道为空(不是我想要的)时,才会停止执行。 只是尝试,我改为执行自己想要的操作的Thread.stop()调用,但我不想将其留在生产代码中。 我意识到我可以使用一个简单的return语句,但这不是线程可以退出的唯一点,我希望有一些通用的退出代码来清理资源。 因此,我的问题是,为什么使用者线程不被中断? 对我来说,有一个通用的退出代码的好方法吗?

谢谢!

当线程正在休眠,等待连接等(基本上是任何可中断的阻塞调用)时,将引发InterruptedException,并调用interrupt()。

如果线程正在运行,则将设置线程中断标志,但不会引发异常,应使用myThread.isInterrupted()检查该标志。

您可以在这里找到更多信息: http : //www.ibm.com/developerworks/java/library/j-jtp05236/index.html

您期望哪个方法抛出InterruptedException Thread.interrupt()不会抛出该Thread.interrupt() ,您的任何方法均不会抛出该Thread.interrupt() 那么,您希望这种检查异常来自何处?

您的代码无法正常工作,因为interrupt()几乎不会在线程上设置interrupted标志。 您必须使用Thread.isInterrupted()显式检查该标志。 仅当相关线程当时正在休眠或阻塞时才抛出InterruptedException 因此,如果您中断另一个线程并且该线程正在睡眠, sleep()将抛出InterruptedException

现在详细解决您的问题。 例外是例外情况 您的线程完成处理不是例外情况,这确实是您所期望的。 出于同样的原因,读取文件的末尾不会引发异常-文件末尾是您绝对应该期望的东西-所有文件均已结束。 此外,您不应使用异常来控制程序流程。

在您的情况下,请使用return语句(当run()返回时,线程死亡)或以其他方式中断循环。 您发布了太多代码以进行分析。

您可以简单地使用break标记

OUTER:
     while(input.available() > 0)
     {
        goodData = input.read(readBuffer);
        while (goodData > 0 )
        {
           System.out.println(readBuffer[0]);
           if ( readBuffer[0] == 27 )
           {
              System.out.println("Consumer: found closing byte and closing thread "+Thread.currentThread().getName());
              //this is the last packet, so interupt thread to close
          //Thread.currentThread().interrupt();
          break OUTER;
          //return;
          //Thread.currentThread().stop(new InterruptedException("Attempting to close"));
           }
           goodData = input.read(readBuffer);
        }
     }

暂无
暂无

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

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