[英]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.