2016-03-07 45 views
-3

我正在嘗試創建Java死鎖程序。我實時知道,我們不會在線程中創建任何死鎖。不幸的是,我在一次採訪中被要求編寫一個「使用兩個線程的死鎖程序」。所以這裏是創建我自己的Java死鎖程序

package Thread.DeadLock; 

public class deadLock2 { 

    static ThreadSample1 t1 = new ThreadSample1(); 
    static ThreadSample2 t2 = new ThreadSample2(); 

    public static void main(String args[]) { 

    t1.start(); 
    t2.start(); 
    } 

    public static class ThreadSample1 extends Thread { 
    public void run() { 
     System.out.println("In first run method"); 
     try { 
     System.out.println("Holding lock in first one"); 
     synchronized (t1) { 
      System.out.println("t1 going to wait for t2"); 

      t1.wait(); 
      System.out.println("t1 finished for waiting"); 
     } 
     } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 
    } 
    } 

    public static class ThreadSample2 extends Thread { 
    public void run() { 
     System.out.println("In second run method"); 
     try { 
     System.out.println("Holding lock for second one"); 
     synchronized (t2) { 
      System.out.println("t2 going to wait for t1"); 

      t2.wait(); 
      System.out.println("t2 finished for waiting"); 
     } 
     } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } 
    } 
    } 
} 

我可以看到程序卡住了。我假設它處於僵局。 t1.start()等待t2完成其任務,t2.start()等待t1完成其任務。現在,當我嘗試通過使用t1.notify()通知等待的線程來消除死鎖時,我得到IllegalMonitorStateException。 有人可以告訴在這種情況下如何消除死鎖而不會造成任何情況。

+0

你爲什麼要引用t1和t2變量?你不應該通過使用引用來明確地處理線程。 – mlewandowski

+0

你的代碼是否表現出[4對於死鎖的必要和充分的要求](http://nob.cs.ucdavis.edu/classes/ecs150-1999-02/dl- cond.html)? (我認爲它只展示了這裏列出的前3個)。 –

回答

2

首先,這不是死鎖。正如您正確地描述的那樣,當兩個或更多線程等待其他線程擁有的資源之間存在循環依賴時,通常會出現死鎖。

在這裏,每個線程獨立地等待自己發出的通知,這實際上並不是系統中其他任何人提供的。即使沒有死鎖。

其次,IllegalMonitorStateException意味着您嘗試通知/等待監視器不被線程保持。換句話說,在notify/wait之前沒有​​。

第三,要實現真正意義上的僵局,你可以做這樣的事情:

synchronized(t1) { 
    synchronized(t2) { 
     t2.wait(); 
    } 
    t1.notify(); 
} 

,反之亦然其它線程。

0

除非當前線程擁有該對象的顯示器,否則不能調用notify()/notifyAll()。要做到這一點,你必須在它同步,如您wait()

Javadocs for wait()提這個做:

此方法應該僅由一個線程,它是此對象監視器的所有者被調用。請參閱notify方法,瞭解線程可以成爲監視器所有者的方式。

拋出:

IllegalMonitorStateException - 如果當前線程不是此對象的監視器的所有者。

而且從notify()

甲線程成爲對象監視器的三種 方式之一的所有者:

  • 通過執行對象的同步實例方法。
  • 通過執行在對象上同步的​​語句的主體。
  • 對於Class類型的對象,通過執行該類的同步靜態方法。

看到這個答案:

Java Wait and Notify: IllegalMonitorStateException