天天看點

面試阿裡被P8質問:ConcurrentHashMap真的線程安全嗎?(下)

性能測試

  • 使用StopWatch測試兩段代碼的性能,最後的斷言判斷Map中元素的個數及所有V的和是否符合預期來校驗代碼正确性
  • 面試阿裡被P8質問:ConcurrentHashMap真的線程安全嗎?(下)
  • 性能測試結果:
  • 面試阿裡被P8質問:ConcurrentHashMap真的線程安全嗎?(下)
  • 比使用鎖性能提升至少5倍。

computeIfAbsent高性能之道

Java的Unsafe實作的CAS。

它在JVM層確定寫入資料的原子性,比加鎖效率高:

static final <K,V> boolean casTabAt(Node<K,V>[] tab, int i,
                                    Node<K,V> c, Node<K,V> v) {
    return U.compareAndSetObject(tab, ((long)i << ASHIFT) + ABASE, c, v);
}      

是以不要以為隻要用了ConcurrentHashMap并發工具就是高性能的高并發程式。

使用computeIfAbsent、putIfAbsent

當Key存在的時候,如果Value擷取比較昂貴的話,putIfAbsent就白白浪費時間在擷取這個昂貴的Value上(這個點特别注意)

Key不存在的時候,putIfAbsent傳回null,小心空指針,而computeIfAbsent傳回計算後的值

當Key不存在的時候,putIfAbsent允許put null進去,而computeIfAbsent不能,之後進行containsKey查詢是有差別的(當然了,此條針對HashMap,ConcurrentHashMap不允許put null value進去)

參考