同步调用锁定条件的 signalAll() 时出现 IllegalMonitorStateException

IllegalMonitorStateException on a synchronized call to a Lock Condition's signalAll()

我有:

static public final ReentrantLock lock  = new ReentrantLock();
static public Condition my_condition    = lock.newCondition();

myClass_1myClass_2 class 我打电话给:

synchronized (myClass_1.my_condition){
    myClass_1.my_condition.signalAll();
}

这给了我 java.lang.IllegalMonitorStateException。我已经通过 signall() 调用进行同步。可能是什么原因造成的?

这是因为您在发送信号之前没有获得 ReentrantLock 的锁。

阅读以下来自 ReentrantLock#newCondition

的重要声明

If this lock is not held when any of the Condition waiting or signalling methods are called, then an IllegalMonitorStateException is thrown.

此外,请阅读以下来自 Condition 的内容。现在,就像如果线程未获取锁则无法调用 wait() 一样,如果未获取锁则等待或发出条件信号。

Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.


底线:在等待或发出条件信号之前获取锁。

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.

不要将 synchronized 与锁一起使用。锁和条件替换 synchronized/wait/notify;它们绝不能与它结合使用。

documentation for ReeantrantLock.newCondition 状态:

If this lock is not held when any of the Condition waiting or signalling methods are called, then an IllegalMonitorStateException is thrown.

正确使用 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 循环中调用,因为 await* 方法会受到虚假唤醒 (就像 Object.wait* 方法一样)。