InterruptedException未被捕获

时间:2016-06-23 04:13:10

标签: java multithreading

我正在学习Java并发,并尝试了Java教程中的一个示例,并进行了一些实验(尝试捕获异常)。

public class SleepMessages {
    public static void main(String args[]) {
        String importantInfo[] = {
            "Mares eat oats",
            "Does eat oats",
            "Little lambs eat ivy",
            "A kid will eat ivy too"
        };

        try { // my experiment
            for (int i = 0; i < importantInfo.length; i++) {
                Thread.sleep(4000);
                System.out.println(importantInfo[i]);
            }
        }
        catch (InterruptedException ie) {
            System.out.println("caught InterruptedException");
        }
    }
}

我尝试向外发送一个中断信号,通过&#34; kill -2 $ PID&#34;。

我预计当处理处于休眠状态时,信号会导致Thread.sleep()抛出异常,然后我就可以捕获它,但实际上并没有!

有人可以解释为什么吗? (我想知道它可能是我发送信号的方式(kill -2)是不正确的。)

3 个答案:

答案 0 :(得分:3)

从外部处理SIGINT信号的方法是在您的应用中注册shutdown hook

public class Main
{
    public static void main(final String[] args) throws InterruptedException
    {
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                System.out.println("Shutdown hook called!");
            }
        });

        while (true)
        {
            Thread.sleep(1000);
        }
    }
}

现在,当您启动程序并使用kill -2 <PID>将其终止时,将调用关闭挂钩并且您可以正常关闭。

当您使用InterruptedException从应用程序内部中断线程时,可以捕获interrupt()(您想要做什么),如以下基本示例所示:< / p>

public class Main
{
   public static void main( final String[] args )
   {

      final Thread t1 = new Thread()
      {
         @Override
         public void run()
         {
            try
            {
               while ( true )
               {
                  Thread.sleep( 1000 );
               }

            }
            catch ( final InterruptedException e )
            {
               System.out.println( "This thread was interrupted!" );
            }
         }
      };
      t1.start();
      t1.interrupt();
   }
}

BR

答案 1 :(得分:2)

当您在相关主题上调用InterruptedException时,会发现

Thread.interrupt()。它与kill程序没有任何关系。

答案 2 :(得分:0)

我在我的ubuntu机器上尝试了相同的场景,发现当我们使用kill命令杀死一个进程时,它基本上会杀死整个进程,所以这个行为就像System.exit(1),但被中断的异常是不同的东西,其中中断状态标志被设置为告诉线程它已从其他线程接收到中断,还有一件事,如果某个其他线程将通过调用此线程实例上的interrupt()方法来中断此线程,那么您将仅当当前线程处于休眠或等待状态时才获取InterruptedException。如果线程正在运行,那么在其上调用interrupt()方法只会将中断标志设置为true(检查中断状态标志,您可以通过此线程实例上的isInterrupted()方法检查),并且不会抛出InterruptedException

参见下面的代码,这里我使用了System.exit(1),在另一个线程中,您将看到整个Java进程已退出,没有中断的异常,原因如上所述。

     public static void main(String args[]) {
        String importantInfo[] = {
                "Mares eat oats",
                "Does eat oats",
                "Little lambs eat ivy",
                "A kid will eat ivy too"
        };

        try { // my experiment
            while(true) {
                Thread.sleep(4000);
                Thread t = new Thread() {
                  public void run() {
                      try {
                          Thread.sleep(1000);
                          System.exit(1);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
                };
                t.start();

                System.out.println(importantInfo[0]);
            }
        }
        catch (InterruptedException ie) {
            System.out.println("caught InterruptedException");
        }
    }

以上修改代码的输出:

  

Mares吃燕麦

     

使用退出代码1完成处理