对锁定条件的同步调用的IllegalMonitorStateException信号All()

时间:2015-07-22 11:12:53

标签: java multithreading locking synchronized

我有:

var updateId = 2;
var elementIdx = dataIndex [`id` + updateId];
data[elementIdx] = myNewData;
delete dataIndex[elementIdx]
dataIndex['id' + myNewData.id] = elementIdx;

static public final ReentrantLock lock = new ReentrantLock(); static public Condition my_condition = lock.newCondition(); myClass_1类中我致电:

myClass_2

这给了我synchronized (myClass_1.my_condition){ myClass_1.my_condition.signalAll(); } 。我已经在java.lang.IllegalMonitorStateException来电同步了。可能导致什么呢?

2 个答案:

答案 0 :(得分:3)

这是因为在发出信号之前你没有获得ReentrantLock的锁定。

阅读以下ReentrantLock#newCondition

的重要声明
  

如果在任何条件等待或时,此锁定不   调用信令方法,然后是IllegalMonitorStateException   抛出。

另请参阅以下Condition。现在,就像你不能在线程没有获得锁定时调用wait()一样,如果没有获得锁定,你就等待或发出信号条件。

  

如果Lock取代了同步方法和语句的使用,   条件取代了对象监视器方法的使用


底线:在等待或发信号通知之前获取锁。

lock.lock();  //Get the lock
while(/* whatever is your condition in myClass_1 and myClass_2 */){  //Or negative condition you want, but some code logic condition...
    my_condition.await();
}
my_condition_2.signal(); //If you want to notify one thread. Like in case of Java's blocking queue, if you want to notify one thread to put or take.
my_condition_2.signalAll(); //If you want to notify all threads.

答案 1 :(得分:1)

请勿将synchronized与锁定一起使用。锁和条件替换synchronized / wait / notify;它们永远不应与它结合使用。

documentation for ReeantrantLock.newCondition州:

  

如果在调用任何Condition等待或信令方法时未保持此锁定,则抛出IllegalMonitorStateException

正确使用Lock和Condition,如下所示:

lock.lock();
try {
    someFlag = true;
    condition.signalAll();
} finally {
    lock.unlock();
}

其他地方:

lock.lock();
try {
    someFlag = false;
    while (!someFlag) {
        condition.await();
    }
} finally {
    lock.unlock();
}

所有Condition.await *方法必须在while循环中调用,该循环检查Condition表示的数据,因为await *方法受到虚假唤醒(就像Object.wait *一样)方法)。