天天看點

HashTable HashMap ConcurrentHashMap

Hashtable是線程安全的,它的方法是同步了的,可以直接用 在多線程環境中。

而HashMap則不是線程安全的。在多線程環境中,需要手動實作同步機制。

效率低下的HashTable容器

HashTable容器使用synchronized來保證線程安全,但線上程競争激烈的情況 下HashTable的效率非常低下。因為當一個線程通路HashTable的同步方法時,其他線程通路HashTable的同步方法時,可能會進入阻塞 或輪詢狀态。

鎖分段技術

HashTable容器在競争激烈的并發環境下表現出效率低下的原因是所有通路HashTable的線程都必須競争同一把鎖,那假如容器裡有多把 鎖,每一把鎖用于鎖容器其中一部分資料,那麼當多線程通路容器裡不同資料段的資料時,線程間就不會存在鎖競争,進而可以有效的提高并發通路效率,這就是 ConcurrentHashMap所使用的鎖分段技術,首先将資料分成一段一段的存儲,然後給每一段資料配一把鎖,當一個線程占用鎖通路其中一個段資料 的時候,其他段的資料也能被其他線程通路。

java5中新增了ConcurrentMap接口和它的一個實作類 ConcurrentHashMap。ConcurrentHashMap提供了和Hashtable以及SynchronizedMap中所不同的鎖機 制。

Hashtable中采用的鎖機制是一次鎖住整個hash表,進而同一時刻隻能由一個線程對其進行操作;而ConcurrentHashMap中則是 一次鎖住一個桶。

ConcurrentHashMap預設将hash表分為16個桶,諸如get,put,remove等常用操作隻鎖目前需要用到的桶。 這樣,原來隻能一個線程進入,現在卻能同時有16個寫線程執行,并發性能的提升是顯而易見的。

上面說到的16個線程指的是寫線程,而讀操作大部分時候都不需要用到鎖。隻有在size等操作時才需要鎖住整個hash表。