幾種線程安全的Map解析


轉載自 面試必問-幾種線程安全的Map解析

 

HashMap線程安全的嗎?

 

Java中平時用的最多的Map集合就是HashMap了,它是線程不安全的。

 

看下面兩個場景:

 

1、當用在方法內的局部變量時,局部變量屬於當前線程級別的變量,其他線程訪問不了,所以這時也不存在線程安全不安全的問題了。

 

2、當用在單例對象成員變量的時候呢?這時候多個線程過來訪問的就是同一個HashMap了,對同個HashMap操作這時候就存在線程安全的問題了。

 

 

線程安全的Map

 

為了避免出現場景2的線程安全的問題,不能使用HashMap作為成員變量,要尋求使用線程安全的Map,下面來總結下有哪些線程安全的Map呢?

 

1、HashTable

 

private Map<String, Object> map = new Hashtable<>();

 

來看看HashTable的源碼

 

 

 

HashTable的get/put方法都被synchronized關鍵字修飾,說明它們是方法級別阻塞的,它們占用共享資源鎖,所以導致同時只能一個線程操作get或者put,而且get/put操作不能同時執行,所以這種同步的集合效率非常低,一般不建議使用這個集合。

 

2、SynchronizedMap

 

private Map<String, Object> map = Collections.synchronizedMap(new HashMap<String, Object>());

 

這種是直接使用工具類里面的方法創建SynchronizedMap,把傳入進行的HashMap對象進行了包裝同步而已,來看看它的源碼。

 

 

這個同步方式實現也比較簡單,看出SynchronizedMap的實現方式是加了個對象鎖,每次對HashMap的操作都要先獲取這個mutex的對象鎖才能進入,所以性能也不會比HashTable好到哪里去,也不建議使用。

 

3、ConcurrentHashMap - 推薦

 

 

private Map<String, Object> map = new ConcurrentHashMap<>();

 

這個也是最推薦使用的線程安全的Map,也是實現方式最復雜的一個集合,每個版本的實現方式也不一樣,在jdk8之前是使用分段加鎖的一個方式,分成16個桶,每次只加鎖其中一個桶,而在jdk8又加入了紅黑樹和CAS算法來實現。

 

 

雖然實現起來很復雜,但使用起來也是非常簡單的,在java面試中問的頻率也非常高,最重要的是性能要比上面兩種同步方式要快太多,推薦使用。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM