2017-05-02 61 views
1

嗨寫了一個示例程序來測試在java中等待的行爲。非法監視器狀態當兩個花等待時異常

我實現Runnable接口的:

class ThreadWait implements Runnable { 
    Object lock = new Object(); 
    ThreadWait(Object lock){ 
     this.lock = lock; 
    } 
    @Override 
    public void run() { 
     try { 
      synchronized (lock){ 
       System.out.println("Started : "+Thread.currentThread().getName()); 
       wait(); 
       System.out.println("Completed : "+Thread.currentThread().getName()); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

使用中我main像:

Object lock = new Object(); 
ThreadWait t1 = new ThreadWait(lock); 
ThreadWait t2 = new ThreadWait(lock); 
Thread a= new Thread(t1); 
a.setName("A"); 
Thread b= new Thread(t2); 
b.setName("B"); 
a.start(); 
b.start(); 

運行這個程序,我得到這個異常:

Exception in thread "A" Exception in thread "B" java.lang.IllegalMonitorStateException 
Started : A 
    at java.lang.Object.wait(Native Method) 
Started : B 
    at java.lang.Object.wait(Object.java:502) 
    at ThreadWait.run(SynchronizedExample.java:34) 
    at java.lang.Thread.run(Thread.java:745) 
java.lang.IllegalMonitorStateException 
    at java.lang.Object.wait(Native Method) 
    at java.lang.Object.wait(Object.java:502) 
    at ThreadWait.run(SynchronizedExample.java:34) 
    at java.lang.Thread.run(Thread.java:745) 
+0

'lock.wait()'...? – MadProgrammer

回答

6

你的問題是,您在lock上同步,但您正在等待this(具體而言:包含等待呼叫的Runnable的實例)。

您只能在擁有顯示器的對象上調用等待。您的代碼擁有lock,但不是this

所以你應該等待鎖對象。但是請注意:那麼你的代碼會死鎖!

這導致了建議:你應該多學習一下「理論」。你看,可以使用wait/notify來「同步」不同的線程,這些線程應該在同一個數據上工作;但這不是你通過反覆試驗(高效)學習的東西;因爲有太多微妙的細節會影響試驗和錯誤實驗的結果。您可能會開始閱讀herethere。最後一句話:理解這一點也很重要,是的,wait/notify是重要的概念;但你很少在「現實世界」中使用它們。這些都是非常低級的機制,Java在其上增加了更強大的抽象。

+0

謝謝你解決了這個問題,是的,我試圖創造僵局。 – robin