2016-10-13 2 views
0

Я написал простую программу, чтобы узнать о синхронизированном блоке. Программа выглядит следующим образом:meet IllegalMonitorStateException при выполнении многопоточного программирования в Java

public class SychronizedBlock { 

    static int balance = 0; 
    static Integer lock = 0; 


    public static void deposit(int amt) { 
     Thread t1 = new Thread(new Runnable() { 
      public void run() { 
       acquire_lock(); 
       int holdings = balance; 
       balance = holdings + amt; 
       System.out.println("deposit " + amt + ", balance: " + balance); 
       release_lock(); 
      } 
     }); 
     t1.start(); 

    } 

    public static void acquire_lock() { 
     synchronized(lock) { 
      while (lock == 1) { 
       try { 
        lock.wait(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      lock = 1; 
     } 
    } 

    public static void release_lock() { 
     synchronized(lock) { 
      lock = 0; 
      lock.notifyAll(); 
     } 
    } 

    public static void test1() { 
     balance = 0; 
     deposit(500); 
     deposit(500); 
    } 

    public static void main(String[] args) { 
     test1(); 
    } 
} 

Однако, при запуске программы, я встретился с IllegalMonitorStateException. Я думаю, что у меня есть функция wait() и notifyAll() в синхронизированном блоке, и я установил блокировку как параметр синхронизации. Почему у меня все еще есть Исключение?

ответ

0

Проблема с вашим методом release_lock. Вы переназначаете lock в 0 перед вызовом lock.notifyAll(). Это означает, что notifyAll будет вызван в новый объект Integer, который не заблокирован. Измените код следующим образом, чтобы исправить проблему.

public static void release_lock() { 
    synchronized(lock) {    
     lock.notifyAll(); 
     lock = 0; 
    } 
} 
+1

Или лучше не менять переменную 'lock'. Очень редко - если когда-либо - хорошая идея синхронизировать переменную, которая может измениться. (Я бы также избежал использования 'Integer' для блокировок из-за эффекта кеширования. Обычно я предпочитаю блокировать простой« объект », который используется для этого просто *. * –

+0

Получите это! Большое вам спасибо за четкое объяснение! Я не понял, что оператор «lock = 0» назначит новый объект для блокировки раньше. – Tom

+0

И спасибо Jon за ваш хороший совет! – Tom

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