简体   繁体   English

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

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

I am working on an application that reads and processes data over a network. 我正在开发一个通过网络读取和处理数据的应用程序。 While testing the connecting/disconnecting logic of the program I noticed that my consumer thread was not closing when it reached it's closing condition. 在测试程序的连接/断开逻辑时,我注意到我的使用者线程在达到关闭状态时并未关闭。 Below is a stripped out version of the consumer class. 下面是消费者类的精简版。

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());
   }
}

I created a dummy main class that demonstrates the problem. 我创建了一个虚拟的主类来演示该问题。

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");
      }
   }
}

When you run this code as written, the consumer detects the interrupt, but does not stop execution until the pipe is empty (not what I want). 当您按编写的方式运行此代码时,使用者将检测到中断,但是直到管道为空(不是我想要的)时,才会停止执行。 Just to try, I changed to a Thread.stop() call which did what I wanted, but I don't want to leave that in production code. 只是尝试,我改为执行自己想要的操作的Thread.stop()调用,但我不想将其留在生产代码中。 I realized that I could use a simple return statement, but this is not the only point the thread could exit, and I'd like to have some common exit code that cleans up resources. 我意识到我可以使用一个简单的return语句,但这不是线程可以退出的唯一点,我希望有一些通用的退出代码来清理资源。 So, my question is, why is the consumer thread not being interrupted? 因此,我的问题是,为什么使用者线程不被中断? and is there a good way for me to be able to have common exit code? 对我来说,有一个通用的退出代码的好方法吗?

Thanks! 谢谢!

InterruptedExceptions are thrown when a thread is sleeping, waiting for a join etc. (basically any interruptable blocking call) and interrupt() is called. 当线程正在休眠,等待连接等(基本上是任何可中断的阻塞调用)时,将引发InterruptedException,并调用interrupt()。

If you thread is running then the thread interrupt flag will be set but no exception will be thrown, you should check the flag with myThread.isInterrupted() . 如果线程正在运行,则将设置线程中断标志,但不会引发异常,应使用myThread.isInterrupted()检查该标志。

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

Which method do you expect to throw InterruptedException ? 您期望哪个方法抛出InterruptedException Thread.interrupt() is not throwing it, neither any of your methods. Thread.interrupt()不会抛出该Thread.interrupt() ,您的任何方法均不会抛出该Thread.interrupt() So where do you expect this checked exception should come from? 那么,您希望这种检查异常来自何处?

Your code is not working because interrupt() barely sets the interrupted flag on a thread. 您的代码无法正常工作,因为interrupt()几乎不会在线程上设置interrupted标志。 You must check that flag explicitly using Thread.isInterrupted() . 您必须使用Thread.isInterrupted()显式检查该标志。 InterruptedException is only thrown if the thread in question was sleeping or blocking at the time. 仅当相关线程当时正在休眠或阻塞时才抛出InterruptedException So if you interrupt different thread and that thread was sleeping, sleep() will throw InterruptedException . 因此,如果您中断另一个线程并且该线程正在睡眠, sleep()将抛出InterruptedException

Now to address your problem in detail. 现在详细解决您的问题。 Exceptions are for exceptional cases . 例外是例外情况 The fact your thread finished processing is not exceptional case, it's something you definitely expect. 您的线程完成处理不是例外情况,这确实是您所期望的。 For the same reason reading a file past the end is not throwing an exception - end of file is something you should definitely expect - all files have end. 出于同样的原因,读取文件的末尾不会引发异常-文件末尾是您绝对应该期望的东西-所有文件均已结束。 Moreover you should not use exceptions to control program flow. 此外,您不应使用异常来控制程序流程。

In your case either use return statement (when run() returns, thread dies) or break your loop in some other way. 在您的情况下,请使用return语句(当run()返回时,线程死亡)或以其他方式中断循环。 You posted too much code to analyze. 您发布了太多代码以进行分析。

You could simply use break to label 您可以简单地使用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.

相关问题 何时使用thread.interrupt()以及何时抛出InterruptedException - When to use thread.interrupt() and when to throws InterruptedException 总是调用Thread.currentThread()。interrupt(); 捕获InterruptedException时? - Always call Thread.currentThread().interrupt(); when catching an InterruptedException? ThreadPoolExecutor.shutdownNow() 不在线程中抛出 InterruptedException - ThreadPoolExecutor.shutdownNow() not throwing InterruptedException in Thread 从主线程休眠是抛出InterruptedException - sleep from main thread is throwing InterruptedException 使用ExecutorService时不调用Thread.interrupt - Thread.interrupt is not called when using ExecutorService InterruptedException:设置中断标志时是否需要 Thread.currentThread().interrupt() - InterruptedException: Is Thread.currentThread().interrupt() necessary as the interrupted flag is set run()中的当前中断线程不会引发InterruptedException - Interrupt current thread inside run() doesn't throw InterruptedException 我们真的应该在捕获 InterruptedException 后中断当前线程吗? - Should we really interrupt the current thread after catching InterruptedException? 为什么要捕获InterruptedException来调用Thread.currentThread.interrupt()? - Why would you catch InterruptedException to call Thread.currentThread.interrupt()? 获取InterruptedException以忽略中断 - Getting InterruptedException to ignore the interrupt
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM