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

HashMap線程安全的嗎?

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

看下面兩個(gè)場景:

1、當(dāng)用在方法內(nèi)的局部變量時(shí),局部變量屬于當(dāng)前線程級別的變量,其他線程訪問不了,所以這時(shí)也不存在線程安全不安全的問題了。

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

線程安全的Map

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

1、HashTable

private?Map?map?=?new?Hashtable<>();

來看看HashTable的源碼

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

2、SynchronizedMap

private?Map?map?= Collections.synchronizedMap(newHashMap());

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

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

3、ConcurrentHashMap - 推薦

private?Map?map?=?new?ConcurrentHashMap<>();

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

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容