[英]Can't understand this multi-threading exception behavior
根據ReentrantLock.newCondition()的文檔,調用線程在調用信號方法之前需要擁有一個鎖:
如果在調用任何條件等待或信號方法時未持有此鎖,則會拋出 IllegalMonitorStateException。
事實上,這就是我在嘗試時看到的:
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signalAll(AbstractQueuedSynchronizer.java:1954)
at PingPongPrinter_.printPing(PingPong2.java:35)
at WorkerPing.run(PingPong2.java:53)
at java.lang.Thread.run(Thread.java:748)
那么為什么這個限制存在於java.util.concurrent.locks.ReentrantLock
中呢? 我相信C++ 沒有這樣的限制。
回答原始問題
在發出信號之前,您正在解鎖與條件關聯的鎖。 從文檔:
在調用此方法時,實現可能(並且通常確實)要求當前線程持有與此條件關聯的鎖。 實現必須記錄此先決條件以及在未持有鎖時采取的任何操作。 通常,會拋出 IllegalMonitorStateException 等異常。
此外,僅鎖定修改您調節的值所需的時間。
void printPong() throws Exception {
// wait for pong condition
while (isPing) {
blockPong.await();
}
rlock.lock();
isPing = true; // modify value
blockPing.signalAll(); // signal ping
rlock.unlock();
System.out.println("Pong");
}
void printPing() throws Exception {
// wait for ping condition
while (!isPing) {
blockPing.await();
}
rlock.lock();
isPing = false; // modify value
blockPong.signalAll(); // signal pong
rlock.unlock();
System.out.println("Ping");
}
修改問題的答案
那么java.util.concurrent.locks.ReentrantLock為什么會有這個限制呢? 我相信C++中沒有這樣的限制。
因為ReentrantLock
是互斥的。 它提供在任何給定時間對一個線程的訪問。 這是一個設計選擇。
在 C++ 中, std::condition_variable
還要求您擁有該資源的互斥量才能發出信號。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.