考慮到的ConcurrentHashMap的javadoc狀態:ConcurrentHashMap的迭代guarrantee
「迭代器和枚舉的或自創建迭代器的返回在某一點反映 哈希表的狀態元素」我想我保證在下面的例子中,一個或兩個線程都會調用fireAllFinished()。有沒有情況下都不會調用fireAllFinished()?
ConcurrentHashMap<String, Boolean> taskToFinished = new ConcurrentHashMap();
taskToFinished.put("taskA", false);
taskToFinished.put("taskB", false);
public void checkForAllFinished() {
boolean allFinished = true;
for (Boolean taskFinished = tasksToFinished.values()) {
if (!taskFinished) {
allFinished = false;
break;
}
}
if (allFinished) {
fireAllFinished()
}
}
//Thread1
public void run() {
taskToFinished.put("taskA", true);
checkForAllFinished();
}
//Thread1
public void run() {
taskToFinished.put("taskB", true);
checkForAllFinished();
}
(我省略了一些創建線程的代碼的希望意圖十分明顯。)
更新:我已經看到了更一般的問題:Is iterating ConcurrentHashMap values thread safe?,但希望確認我的具體點作爲
「在某些點」
通常是一IMP在處理運行代碼亂序的多核機器時提出概念,兩個線程可能會同時更新映射的不同段,並且設計無法鎖定整個ConcurrentHashMap。
此程序不起作用。方法'checkForAllFinished'有一個局部變量'allFinished'。局部變量總是線程安全的,因爲它們在堆棧上,而其他線程永遠不會看到它們。出於這個原因,你的'checkForAllFinished'方法將不會像你期望的那樣工作。如果您將'allFinished'作爲實例字段,則需要將其同步或設置爲volatile以防止陳舊的數據。 – scottb
@scottb你說的沒有錯。 – Jason
如果您正在等待完成一組任務,爲什麼不使用「未來」? – Jason