我有一個列表,我在我的函數doMapOperation
中的名稱爲synchronizedMap
上同步。在這個函數中,我需要添加/刪除地圖中的項目並對這些對象執行昂貴的操作。我知道我不想在同步塊中調用昂貴的操作,但我不知道在執行這些操作時如何確保地圖處於一致狀態。什麼是正確的方法來做到這一點?收集昂貴操作的Java同步
這是因爲要避免在同步塊調用一個昂貴的操作我的,我敢肯定初始佈局是錯誤的:
public void doMapOperation(Object key1, Object key2) {
synchronized (synchronizedMap) {
// Remove key1 if it exists.
if (synchronizedMap.containsKey(key1)) {
Object value = synchronizedMap.get(key1);
value.doExpensiveOperation(); // Shouldn't be in synchronized block.
synchronizedMap.remove(key1);
}
// Add key2 if necessary.
Object value = synchronizedMap.get(key2);
if (value == null) {
Object value = new Object();
synchronizedMap.put(key2, value);
}
value.doOtherExpensiveOperation(); // Shouldn't be in synchronized block.
} // End of synchronization.
}
我想爲這個問題的延續,你會怎麼做在一個循環?
public void doMapOperation(Object... keys) {
synchronized (synchronizedMap) {
// Loop through keys and remove them.
for (Object key : keys) {
// Check if map has key, remove if key exists, add if key doesn't.
if (synchronizedMap.containsKey(key)) {
Object value = synchronizedMap.get(key);
value.doExpensiveOperation(); // Shouldn't be here.
synchronizedMap.remove(key);
} else {
Object value = new Object();
value.doAnotherExpensiveOperation(); // Shouldn't here.
synchronizedMap.put(key, value);
}
}
} // End of synchronization block.
}
感謝您的幫助。
這裏沒有足夠的信息來了解在緩慢操作期間是否可以放棄鎖。關鍵問題是所有這些工作是否似乎都以原子方式發生在其他線程上?如果不是,哪些操作應該顯示爲原子?那麼操作是否必須在整個地圖上自動發生?換句話說,如果您可以確保單個密鑰上的操作是原子性的,那該怎麼辦? – erickson