![](/img/trans.png)
[英]Is ConcurrentHashMap<Integer, ArrayList<Object>> Thread safe?
[英]Can I use ConcurrentHashMap with Integer for thread safe counters?
我想要幾個櫃台,我可以按名稱尋址。 所以,我可以通過這種方式實現它:
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.computeIfAbsent("key", k -> new Integer(0));
map.computeIfPresent("key", (k, v) -> v + 1);
它編碼線程安全嗎?
我認為是的,因為我們因為ConcurrentHashMap
進行了同步訪問,並且設置新引用也是線程安全的操作。 由於安全發布,其他線程會看到這種變化,當我們在ConcurrentHashMap
保留存儲桶鎖時會發生這種情況。
是的,它是線程安全的,您可以測試:
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadsafeExample {
public static void main(String[] args) throws Exception {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
int count = 1000;
AtomicInteger doneTasks = new AtomicInteger();
Thread[] threads = new Thread[count];
for(int i = 0 ; i < threads.length ; ++i) {
threads[i] = new Thread(() -> {
map.computeIfAbsent("key", k -> new Integer(0));
map.computeIfPresent("key", (k, v) -> v + 1);
doneTasks.incrementAndGet();
});
}
for(int i = 0 ; i < threads.length ; ++i)
threads[i].start();
while (doneTasks.get() < count)
Thread.sleep(3);
System.out.println("we expected count of key is: " + count + ", and we get: " + map.get("key"));
}
}
輸出:
we expected count of key is: 1000, and we get: 1000
您可以替換:
map.computeIfAbsent("key", k -> new Integer(0));
map.computeIfPresent("key", (k, v) -> v + 1);
經過
map.compute("key", (k, v) -> v == null ? 1 : v + 1);
假設第一條語句, map.computeIfAbsent("key", k -> new Integer(0));
發生在“初始化時間”,然后有一堆線程執行形式map.computeIfPresent("key", (k, v) -> v + 1);
,是的,算法將是正確的(我是否理解您的意圖?)。
JDK 的最新版本保證對ConcurrentHashMap.computeIfPresent()
調用不僅會調用以線程安全方式傳入的表達式,還會保證如果其他線程同時嘗試對相同的鍵進行操作,它們會阻塞並排隊,這樣所有的變化都會按順序發生(這在分布式系統的說法中稱為可串行化)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.