您的代碼可以用intrinsic lock簡化。
Object sharedObj = new Object();
主線:
synchronized (sharedObj) {
int retryCount = 0;
while (retryCount < maxRetry) {
sharedObj.wait(5000);
retryCount++;
}
}
子線程:
synchronized (sharedObj) {
//do something, may take a long time
Thread.sleep(10);// sleep to simulate a long execution
sharedObj.notify();
}
java的狀態等待超時,但不能返回
這是因爲鎖必須被釋放所以等待/等待才能返回。所以,你的子線程應該是這樣的:
//do something, may take a long time
Thread.sleep(10);// sleep to simulate a long execution
synchronized (sharedObj) {
sharedObj.notify();
}
Java的等待/通知通常是用來解決生產者 - 消費者問題。 而且通常sharedObj不應該持有太久。然後你的主線程可以在等待超時時再次保持鎖定。
看看一個在生產例如:hadoop/hdfs/DFSOutputStream.java 的邏輯很簡單,生產者創建數據包,並把它放在dataQueue
// takes a long time to create packet
synchronized (dataQueue) {
dataQueue.addLast(packet);
dataQueue.notifyAll();
}
消費者等待而dataQueue是空的:
synchronized (dataQueue) {
while ((!shouldStop() && dataQueue.size() == 0 &&...) {
try {
dataQueue.wait(timeout);
} catch (InterruptedException e) {
LOG.warn("Caught exception", e);
}
doSleep = false;
now = Time.monotonicNow();
}
正如你所看到的,dataQueue大多數時間都是解鎖的!
我怎樣才能達到我的要求,主線程等待子線程的信號,但有一個有界的超時?
如果你的子線程大多是在一個循環,你的主線程可以設置isRunning標誌本身,使子線程停止。如果你的子線程主要被I/O操作阻塞,你的主線程可能會中斷子線程。
sharedObj用於協調和保護sharedObj。如果有其它資源應該得到保護,你有2種選擇:
1.如果資源上的操作快捷,像ackQueue在DFSOutputStream.java,一起保護它sharedObj內。
2.如果資源上的操作比較耗時,請在sharedObj以外的地方進行操作。
您是否需要使用'Lock'和'Condition'(如在作業中)?有比簡單的解決方案,而不是建立這樣一個大多數的鎖定和條件的嘗試機制。 – zapl
你的sharedLock的目的是什麼?你想用它來防止什麼? –
@NicolasFilotto我想使用信號並等待。 condition.await和condition.signal必須與鎖一起使用,或者不能調用await和signal方法。 – Moon