2013-08-01 185 views
0
public class TwoThreads { 
    private static Object resource = new Object(); 

    private static void delay(long n) { 
     try 
     { 
      Thread.sleep(n); 
     } 
     catch (Exception e) 
     { 

      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     System.out.print("StartMain "); 
     new Thread1().start(); 
     delay(1000);      //dealay 1 
     Thread t2 = new Thread2(); 
     t2.start(); 
     delay(1000);      // delay 2  
     t2.interrupt();     //here its throwing exception 
     delay(1000);      //delay 3 
     System.out.print("EndMain "); 
    } 

    static class Thread1 extends Thread { 
     public void run() { 
      synchronized (resource) { 
       System.out.print("Startl "); 
       delay(6000); 
       System.out.print("End1 "); 
      } 
     } 
    } 

    static class Thread2 extends Thread { 
     public void run() { 
      synchronized (resource) { 
       System.out.print("Start2 "); 
       delay(2000); 
       System.out.print("End2 "); 
      } 
     } 
    } 
} 

我剛到這兒困惑,爲什麼t2.interrupt()沒有拋出異常,當T2正在等待獲取資源對象和interrupt()方法上的鎖可能會引發安全異常,那麼爲什麼編譯器還允許我們不把它變成try catch塊執行。爲什麼在這裏拋出異常異常......原因?

+1

你的問題還不清楚:你的代碼中的註釋表示拋出了一個異常,但是你的代碼下面的文本顯示沒有拋出異常。而關於安全異常的部分也不是很清楚...... – assylias

+0

是的,它是拋出中斷異常,關於安全異常,這是另一個問題。 – Sunny

回答

2

一個同步塊不會拋出一個InterruptedException異常並在嘗試獲取監視器時中斷線程阻塞,這種方式不會執行任何操作。

如果你想要這個功能,你需要使用一個鎖具有lockInterruptibly(),雖然這不是經常使用。

獲取鎖定,除非當前線程中斷。如果該鎖未被另一個線程持有並立即返回,則獲取 鎖, 將鎖保持計數設置爲1。

如果當前線程已經擁有此鎖定,則保持計數爲 ,並且該方法立即返回。

如果鎖被另一個線程保持,則當前線程, 停用線程調度的目的,一直處於休眠狀態的 發生兩種情況之一:

鎖定由當前線程獲得;或者其他一些線程 中斷當前線程。如果鎖由當前的 線程獲取,則鎖定保持計數設置爲1。

如果當前線程: 在輸入此方法時設置了其中斷狀態;或者在獲取鎖時中斷 ,則拋出InterruptedException爲 ,並清除當前線程的中斷狀態。

+0

安全異常也是運行時異常,因此編譯器不是抱怨的 – veritas

1

Thread#interrupt()

如果沒有以前的條件保存,則該線程的中斷狀態將被設置。

如果選中t2.interrupted(),你會看到一個true結果,但線程被阻塞在進入​​塊,這不會觸發InterruptedException

如果應用程序的環境設置了哪些線程可以與其他線程交互的限制,則調用interrupt()可能會拋出SecurityException,但這不適用於您的簡單示例。

+0

好的,因爲它當時不會觸發InterruptedException,那麼主線程會睡覺延遲3,然後打印endMain,然後在那之後觸發被中斷的異常將被拋出 – Sunny

1

問題不清楚,但我想我理解它是正確的,所以我試圖回答。

syncrhonized塊是不是響應中斷。

爲此,您可以使用顯式鎖Lock,該鎖具有響應中斷的方法lockInterruptibly()

lockInterruptibly() in Lock Interface

0

java.lang.Thread.interrupt()將會裝置中斷該線程。

除非當前線程被中斷本身,它總是允許的,該線程的的checkAccess方法被調用,這可能導致一個拋出:SecurityException被拋出。

如果此線程在調用Object類的wait(),wait(long)或wait(long,int)方法或join(),join(long),join (long,int),sleep(long)或sleep(long,int),該類的方法爲,則其中斷狀態將被清除,並將收到InterruptedException

你在t2上調用了sleep()。這就是中斷異常的原因。

相關問題