HashMap是不是線程安全?
不是線程安全的崇裁。
為什么不安全?
線程不安全的兩個添加是束昵,數(shù)據(jù)可共享拔稳、可修改。HashMap底層是用Node[]數(shù)組來存儲元素锹雏,滿足可共享和可修改壳炎,所以在多線程一起更新時,會得到不可預(yù)期的結(jié)果逼侦。
有什么安全的實(shí)現(xiàn)方式匿辩?
在以前可以用HashTable來代替,它的put榛丢、remove等對方法都加了鎖铲球,在多線程下是安全的。但是鎖加在方法上晰赞,力度太大稼病,導(dǎo)致性能不理想。所以在JDK1.5后引入了并發(fā)包掖鱼,里面的ConcurrentHashMap解決了HashMap線程安全問題和Hashtable的性能問題然走。
為什么ConcurrentHashMap是線程安全的?
ConcurrentHashMap通過加鎖來互斥多線程的修改操作戏挡,但是它鎖力度是每個桶芍瑞,會拿每個桶的第一個元素作為鎖對象,對一個桶進(jìn)行加鎖褐墅。多個桶之間的修改是相互獨(dú)立的拆檬。另外在很多地方用了CAS操作,來避免加鎖妥凳。CAS是通過直接調(diào)用CPU的指令來更新數(shù)據(jù)竟贯,是一個原子性操作,比加鎖開銷要小逝钥。但它是建立在低競態(tài)的前提下屑那。
ConcurrentHashMap可以替代HashMap嗎?
這要根據(jù)不同的場景去分析。如果是在多線程環(huán)境下可能會發(fā)生線程不安全的問題持际,可以用ConcurrentHashMap替代HashMap沃琅;但沒有線程安全問題時,用HashMap性能更好选酗。這跟StringBuilder和StringBuffer一樣阵难。當(dāng)然也可以通過ThreadLocal+HashMap來替代ConcurrentHashMap岳枷,這是一種空間換時間的思想芒填。