經典的同步容器有hashmap以及vector,底層的實現機制無非就是使用synchronized關鍵字對每乙個方法進行修飾,保證容器操作的同步,但是效能很低,無法滿足現如今網際網路時代的高併發要求。
jdk5.0以後便開始使用併發類容器來替代同步類容器,原因是同步容器雖然實現了執行緒安全,但是基本上一次訪問只能有乙個執行緒在操作,極大的降低了效率和併發性,所以慢慢的使用concurrenthashmap來替代hashtable。
首先我們來說說concurrenthashmap和hashtable的區別:hashtable的實現就是把整個物件上一把大鎖,當任何執行緒訪問該物件時,便上鎖,其他物件如果想要訪問該物件,即使操作的不是同乙個段,都會被阻塞,然後等待。
而concurrenthashmap則引入了段segment的概念,對分段加鎖,每乙個分段相當於乙個hashtable,允許併發操作,效率極大地得到了提公升,最多可以有16個段,其通過減小鎖的粒度來降低鎖競爭。
再有就是乙個copyonwrite容器,也是乙個併發容器,簡稱cow容器,顧名思義,也就是在寫的時候會拷貝乙份副本,對原物件不需要進行加鎖,所以當乙個執行緒在寫操作的時候,其他執行緒還是可以對原物件進行讀操作,當寫操作完成時,會把指標指向修改後的物件。適用於讀多寫少的場景,因為,當物件集合十分大的時候,如果有多個執行緒進行寫操作,也就意味著需要頻繁地複製副本,另外也需要加鎖,防止資料不一致的問題。(多個寫是無法併發的,只能同步,讀不加鎖,寫加鎖,就是他的理念)
包括queue佇列資料結構也是有兩種型別的,當然他們都是實現了queue介面的。一種是concurrentlinkedqueue,他是無阻塞佇列,不存在加鎖,可以滿足高併發的需求,也是執行緒安全的,另外一種便是blockingqueue介面,為阻塞佇列,在入隊和出隊時會加鎖,有五種實現方式。簡單介紹下:arrayblockingqueue,是一種定長的阻塞佇列,長度需要定義;linkedblockingqueue,是一種不定產的阻塞佇列,長度可定義;以及乙個無快取佇列,生產者產生的資料會直接被消費者消費;還有具有優先順序的佇列,資料物件必須實現compareable介面;和delayqueue,其中的資料元素只有指定的時間到了,才能被獲取,元素必須實現delayed介面。他們的方法有add,offer,poll,take。(阻塞佇列和非阻塞佇列都是執行緒安全的,區別在於阻塞佇列對入隊和出隊上了鎖,而非阻塞佇列沒有上鎖,採用cas演算法實現,效率很高,兩者都能滿足多執行緒併發場景,只是非阻塞佇列需要手動編寫**進行取元素非空的判斷)
同步容器與併發容器
同步容器 可以簡單地理解為通過synchronized來實現同步的容器,如果有多個執行緒呼叫同步容器的方法,它們將會序列執行。比如vector,hashtable 早起jdk的一部分 及collections.synchronized 等方法返回的容器。可以通過檢視vector,hashtable等...
同步容器與併發容器
同步容器 可以簡單地理解為通過synchronized來實現同步的容器,如果有多個執行緒呼叫同步容器的方法,它們將會序列執行。比如vector,hashtable 早起jdk的一部分 及collections.synchronized 等方法返回的容器。可以通過檢視vector,hashtable等...
同步容器和併發容器
同步容器和併發容器 vector 執行緒安全,在方法上加synchronized arraylist collections 工具類 hashtable 執行緒安全,在方法上加synchronized hashmap 併發容器 copyonwritearraylist 當寫的時候,就複製。缺點 1 ...