我有以下代碼:Condition實例signalAll()不返回
@Log4j
public class ItemStore {
final Lock lock = new ReentrantLock();
final Condition hasItem = lock.newCondition();
private Map<String, String> store = new Hashtable<>();
public void put(String handle, String item) {
store.put(handle, item);
log.info("stored " + handle);
hasItem.signalAll();
log.info("signaled all threads");
}
public String fetchWithTimeout(String handle, long timeoutInSec) throws InterruptedException {
try {
lock.lock();
while (!store.containsKey(handle)) {
log.info("store doesn't have " + handle + "; keep waiting");
hasItem.await(timeoutInSec, TimeUnit.SECONDS);
}
return store.get(handle);
} finally {
lock.unlock();
}
}
}
@Test
public void test_withPut() throws InterruptedException {
ItemStore itemStore = new ItemStore();
final String key = "foo";
final String value = "bar";
new Thread() {
@Override
public void run() {
try {
Thread.sleep(3000);
log.info("slept 3 seconds");
itemStore.put(key, value);
} catch (Exception e) {
}
}
}.start();
log.info("fetching");
String actual = itemStore.fetchWithTimeout(key, 20);
log.info("actual = " + actual);
assertEquals(actual, value);
}
基於從如下測試日誌:
2014-10-05 17:52:48 INFO com.tns.ct.downloader.tests.commons.ItemStoreTest.test_withPut():36 - fetching
2014-10-05 17:52:48 INFO com.tns.ct.downloader.tests.commons.ItemStore.fetchWithTimeout():30 - store doesn't have foo; keep waiting
2014-10-05 17:52:51 INFO com.tns.ct.downloader.tests.commons.ItemStoreTest.run():29 - slept 3 seconds
2014-10-05 17:52:51 INFO com.tns.ct.downloader.tests.commons.ItemStore.put():21 - stored foo
2014-10-05 17:53:08 INFO com.tns.ct.downloader.tests.commons.ItemStoreTest.test_withPut():38 - actual = bar
似乎hasItem.signalAll()
已經一去不返,因爲signaled all threads
日誌從未發佈過。另一個線索是程序僅在達到20秒超時時退出。那麼,爲什麼在這種情況下signalAll()
方法被阻止?
你的代碼有些奇怪。您在匿名Thread子類中使用'itemStore'而不使用變量爲final。檢查是否沒有使用類中的任何'ItemStore'實例。 – mp911de 2014-10-05 18:23:31
@ mp911de:他可能正在使用Java 8,其中final不再是必需的。該變量只能是有效的最終變量,編譯器會檢測它是否並非全部。 – 2014-10-05 18:35:52
與這個特定的問題無關,推薦的習慣用法是立即* try-finally塊之外的鎖。 – 2014-10-08 20:31:22