簡體   English   中英

沒有捕獲InterruptedException

[英]InterruptedException is not being caught

我正在學習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");
        }
    }
}

我嘗試通過“ kill -2 $ PID”向外部發送一個中斷信號。

我希望在處理處於休眠狀態時,該信號將導致Thread.sleep()引發異常,然后我可以捕獲到該異常,但實際上不是!

誰能解釋為什么? (我想知道這也許是我發送信號的方式(kill -2不正確)。)

處理來自外部的SIGINT信號的方法是在應用程序中注冊一個關閉鈎子

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>將其終止時,將調用shutdown鈎子,您可以正常關閉。

當您使用interrupt() 從應用程序內部中斷線程時,可以捕獲InterruptedException (您想要做什么interrupt()如以下非常基本的示例所示:

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

當您在有問題的線程上調用Thread.interrupt() ,將捕獲InterruptedException 它與kill程序無關。

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

上面修改的代碼的輸出:

母馬吃燕麥

流程以退出代碼1完成

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM