我有:
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
来电同步了。可能导致什么呢?
答案 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 *一样)方法)。