Kevin Bourrillion是對的。您構建的地圖不是線程安全的技術原因是,即使您使用的地圖是線程安全的,表操作也可能不是。讓我給放的例子,如StandardTable
,這是使用Tables.newCustomTable
實現:
public V put(R rowKey, C columnKey, V value) {
Map<C, V> map = backingMap.get(rowKey);
if (map == null) {
map = factory.get();
backingMap.put(rowKey, map);
}
return map.put(columnKey, value);
}
線程安全的map == null
案件處理損害。也就是說,兩個或更多個線程可以進入該塊併爲columnKey
創建新條目,並且執行backingMap.put(rowKey, map)
的最後一個將最終覆蓋backingMap
中的columnKey
的條目,這將導致丟失由其他執行的put
操作線程。特別是在多線程環境下這種操作的結果是非確定性的,這相當於說這個操作不是線程安全的。
的正確實施此方法的是:
public V put(R rowKey, C columnKey, V value) {
ConcurrentMap<C, V> map = table.get(rowKey);
if (map == null) {
backingMap.putIfAbsent(rowKey, factory.get());
}
map = backingMap.get(rowKey);
return map.put(columnKey, value);
}
我目前正在調查是否可以使用ForwardingTable
實現與你想做的事一起,來獲得足夠的線程安全ConcurrentTable
。
但說實話,我認爲沒有線程安全的Table
實現的原因是接口本身不提供任何併發結構,如putIfAbsent
或replace
。
你對「並發表」的定義是什麼? –
好問題。用另一種方式來解釋我的問題:這些表會不會以一種併發地圖>的方式炸燬?而通過「爆炸」,我的意思是進入無限循環,拋出異常,或者做任何其他常規HashBaseTable將做的事情,如果你試圖在多線程上同時讀取和寫入它。 –