2013-07-08 49 views
0

我不能使用同步正確:Java同步-IllegalMonitorStateException

在以下我有2個問題的代碼:
1.而makingmethods(designBusiness,createBusiness,sellBusiness)作爲​​像在這種情況下,一個呼叫wait()IllegalMonitorStateException但我不明白爲什麼?因爲在designBusiness方法Designer Thread確實得到一個鎖,所以它應該等待wait呼叫。我在wait()notify()上都收到IllegalMonitorStateException。


2.Even雖然當我刪除​​關鍵字,並使用synchronized(this)塊特別wait()notify()還是我得到了死鎖!爲什麼?

public class Main { 
    HashMap<String, Integer> map = new shop().orderBook(); 

    public static void main(String[] args) throws InterruptedException { 

    Main main = new Main(); 

    main.sellBusiness(); 
    Thread.sleep(3000); 
    main.designBusiness(); 
    Thread.sleep(3000); 
    main.createBusiness(); 
    } 

    private synchronized void designBusiness() throws InterruptedException { 

    Thread designThread = new Thread(new Runnable() { 
     public void run() { 
     Set set = map.keySet(); 
     System.out.println("Tracking OrderList"); 
     System.out.println(set.size()); 
     try { 

      System.out.println("waiting........."); 
      wait(); 
      System.out.println("wait completed"); 

      System.out.println("after design process items in orderList are " 
       + map.keySet().size()); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     } 

    }, "Designer Thread"); 
    designThread.start(); 
    System.out 
    .println("status of Designer Thread" + designThread.isAlive()); 
    } 

    private synchronized void createBusiness() throws InterruptedException { 
    Thread createThread = new Thread(new Runnable() { 

     public void run() { 
     System.out.println(Thread.currentThread().getName() 
      + " started"); 
     Creator creator = new Creator(); 
     creator.create(map); 
     notifyAll(); 
     System.out.println("notified"); 

     } 
    }, "Creator Thread"); 
    createThread.start(); 
    createThread.join(); 
    System.out.println("status of Creator Thread" + createThread.isAlive()); 
    } 

    private void sellBusiness() throws InterruptedException { 
    Thread sellThread = new Thread(new Runnable() { 
     public void run() { 
     Seller seller = new Seller(); 
     seller.sellGold(45000, 15); 
     seller.sellSilver(14000, 60); 
     seller.noteOrder("Mrs Johnson", 15000, map); 
     seller.noteOrder("Mr. Sharma", 10000, map); 
     seller.sellGold(60000, 20); 
     seller.noteOrder("Mr. Hooda", 17500, map); 
     System.out.println(Thread.currentThread().getName() 
      + " done selling"); 
     } 
    }, "Seller Thread"); 
    sellThread.start(); 
    sellThread.join(); 
    System.out.println("status of seller Thread" + sellThread.isAlive()); 
    } 
} 

請幫助我找不到任何解決方案,這個問題,我從昨晚搜索。

+0

DEADLOCK?哪些線程被鎖定?主要和設計師和創造者? – johnchen902

+0

@ johnchen902由於設計師和創作者的原因造成的死鎖。我不認爲是原因。 –

回答

2

如果你有此異常你是不是在描述對象上同步的塊或方法你在等待。這是例外的含義。唯一的含義。

您正在調用的wait()方法在您創建的匿名內部類的實例上執行。您正在創建它的同步方法在不同的對象上進行同步,並且在內部對象進入wait()調用時它可能已經執行。

您需要清理哪個對象是在這裏。可能你需要調用Main.this.wait(),但這取決於你想要做什麼,這在你的問題中是不明確的。

注意你沒有陷入僵局,你會得到一個無限的塊。這不是一回事。

+0

嘿感謝的人!你明白了! –

0

wait()必須從​​塊在相同的監視器上執行。由於wait()相同this.wait()你有synchronized(this)把它包起來:

synchronized(this) { 
    wait(); 
} 
+0

你可能不瞭解我的問題。 1.我使用同步方法,所以不需要同步(這),我猜。 2.即使當我使用同步(這)我得到DEADLOCK。 –

1

wait()notify()notifyAll()必須​​使用。我會做的是試圖解決僵局。


要說明爲什麼你得到了僵局(無關的代碼刪除)(如果我猜得不錯)

public class Main { 
    public static void main(String[] args) throws InterruptedException { 
     Main main = new Main(); 
     main.createBusiness(); 
    } 
    private synchronized void createBusiness() throws InterruptedException { 
//   ^^^^^^^^^^^^ got lock 
     Thread createThread = new Thread(new Runnable() { 
      public void run() { 
       synchronized (Main.this) { 
//    ^^^^^^^^^^^^^^^^^^^^^^^^ try to get lock --> DEADLOCK 
        Main.this.notifyAll(); 
       } 
      } 
     }); 
     createThread.start(); 
     createThread.join(); 
//  ^^^^^^^^^^^^^^^^^^^ wait for createThread to die --> DEADLOCK 
    } 
} 
  1. 主線程得到了Main.this鎖。
  2. createThread試圖鎖定Main.this,但它被鎖定Main.this,因此等待。
  3. 主線程等待createThread死機,等待。 (2和3可以交換)

因爲我不知道你想達到什麼樣的,我不知道,如果下面是正確的解決方案,但你可以嘗試(甚至如果以上猜測錯了):

首先,創建一個lock對象。

public class Test { 
    private Object lock = new Object(); 

其次,在設計線程

synchronized (lock) { 
    lock.wait(); 
} 

三,在創作者螺紋

synchronized (lock) { 
    lock.notifyAll(); 
} 
0

如果您嘗試通過未被該線程鎖定的THA解鎖對象,那麼您最終可能會得到相同的錯誤。