2013-07-08 2 views
0

Am Я не использую синхронизации правильно:Java Синхронизация -IllegalMonitorStateException

В следующий код у меня возникли 2 проблемы:
1. в то время как makingmethods (designBusiness, createBusiness, sellBusiness), как synchronized, как в этом случае, вызов wait() говорит IllegalMonitorStateException, но я не понимаю, почему? потому что в designBusiness метод Designer Thread действительно получить замок, поэтому он должен ждать по телефону wait. Я получаю IllegalMonitorStateException на wait() и notify() оба.


2.Even, хотя, когда я удалить synchronized ключевое слово и использовать 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(), но это зависит от того, что вы думаете, что вы пытаетесь сделать, что неясно из вашего вопроса.

NB Вы не получаете тупик, вы получаете бесконечный блок. Это не одно и то же.

+0

эй спасибо мужчине !!! У меня это получилось! –

0

wait() должен быть выполнен из блока synchronized на том же мониторе. Поскольку wait() такая же, как this.wait() вы должны обернуть его synchronized(this):

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

вы не можете понять мой вопрос. 1. Я использую синхронизированный метод, поэтому нет необходимости синхронизировать (это), я думаю. 2. Даже когда я использую синхронизированный (это), я получаю DEADLOCK. –

1

wait(), notify() и notifyAll() должны использоваться с synchronized. Я бы попытался решить тупик.


Для того, чтобы проиллюстрировать, почему вы получили затор (несвязанный код удален) (если я угадала):

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

Если вы попытаетесь разблокировать onject от threas, который не заблокирован этим потоком, тогда вы можете получить ту же ошибку.

Смежные вопросы