jdk 5.0 以後提供了多種併發類容器來替代同步類容器從而改善效能。同步類容器的 狀態都是序列化的。他們雖然實現了執行緒安全,但是嚴重降低了併發性,在多執行緒環境時, 嚴重降低了應用程式的吞吐量。
併發類容器是專門針對併發設計的,使用 concurrenthashmap 來代替給予雜湊的傳 統的 hashtable,而且在 concurrenthashmap 中,新增了一些常見復合操作的支援。以 及使用了 copyonwritearraylist 代替 voctor,併發的 copyonwritearrayset。
以及 併發的 queue,concurrentlinkedqueue 和 linkedblockingqueue,前者是高效能的隊 列,後者是以阻塞形式的佇列,具體實現 queue 還有很多,例如 arrayblockingqueue、 priorityblockingqueue、synchronousqueue 等。
12.1、concurrenthashmap
由於 hashmap 是執行緒不同步的,雖然處理資料的效率高,但是在多執行緒的情況下存在 著安全問題,因此設計了 currenthashmap 來解決多執行緒安全問題。 hashmap 在 put 的時候,插入的元素超過了容量(由負載因子決定)的範圍就會觸發擴容操作,就是 rehash,這個會重新將原陣列的內容重新 hash 到新的擴容陣列中,在多 執行緒的環境下,存在同時其他的元素也在進行 put 操作,如果 hash 值相同,可能出現同時 在同一陣列下用鍊錶表示,造成閉環,導致在 get 時會出現死迴圈,所以 hashmap 是執行緒 不安全的。
jdk7 下的 concurrenthashmap
在 jdk1.7 版本中,concurrenthashmap 的資料結構是由乙個 segment 陣列和多個 hashentry 組成,主要實現原理是實現了鎖分離的思路解決了多執行緒的安全問題,如下圖 所示:
segment 陣列的意義就是將乙個大的 table 分割成多個小的 table 來進行加鎖,也就 是上面的提到的鎖分離技術,而每乙個 segment 元素儲存的是 hashentry 陣列+鍊錶,這 個和 hashmap 的資料儲存結構一樣。
concurrenthashmap 內部使用段(segment)來表示這些不同的部分,每個段其實就 是個小的 hashtable,它們有自己的鎖。只要多個修改操作發生在不同的段上,它們就可 以併發進行。把乙個整體分成了 16 個段(segment)。也就是最高支援 16 個執行緒的併發修 改操作。這也是在多執行緒場景時減小鎖的粒度從而降低鎖競爭的一種方案。並且**中大多 共享變數使用 volatile 關鍵字宣告,目的是第一時間獲取修改的內容,效能非常好。
jdk8 的 concurrenthashmap
jdk1.8 的實現已經摒棄了 segment 的概念,而是直接用 node 陣列+鍊錶+紅黑樹的數 據結構來實現,併發控制使用 synchronized 和 cas 來操作,整個看起來就像是優化過且執行緒安全的 hashmap,雖然在 jdk1.8 中還能看到 segment 的資料結構,但是已經簡化了 屬性,只是為了相容舊版本。
node 是 concurrenthashmap 儲存結構的基本單元,繼承於 hashmap 中的 entry,用 於儲存資料,node 資料結構很簡單,就是乙個鍊錶,但是只允許對資料進行查詢,不允許 進行修改。
12.2、copyonwrite 容器
copy-on-writef 簡稱 cow,是一種用於程式設計中的優化策略。 jdk 裡的 cow 容器有兩種: copyonwritearraylist 和 copyonwritearrayset, cow 容器非常有用,可以在非常多的併發場景中使用到。
什麼是 copyonwrite 容器?
copyonwrite 容器即寫時複製的容器。通俗的理解是當我們往乙個容器新增元素的時 候,不直接往當前容器新增,而是先將當前容器進行 copy,複製出乙個新的容器,然後新 的容器裡新增元素,新增完元素之後,再將原容器的引用指向新的容器。這樣做的好處是我 們可以對 copyonwrite 容器進行併發的讀,而不需要加鎖,因為當前容器不會新增任何元 素。所以 copyonwrite 容器也是一種讀寫分離的思想,讀和寫不同的容器。
總結:鎖加在每乙個數字元素上面;複製乙份出來,寫完後修改位址。
併發程式設計9 併發容器
解決併發情況下的容器執行緒安全問題 譬如 vector,hashtable,都是給予同步鎖實現的 concurrent包下的類,大部分都是使用系統底層的實現,類似於native public class test09 latch.countdown for thread t arr try catc...
併發容器類Map
hashmap concurrenthashmap 認識了解concurrentskiplistmap 執行緒不安全 擴容時是非原子操作,會存在資料不完整,讀的時候會存在問題,執行緒不安全。從抽象角度,帶著問題看原始碼,看最熟悉的方法,主要關注是什麼而不是為什麼這麼做。jdk1.7版本 儲存資料結構...
java併發程式設計容器
1.concurrenthashmap 雖然hashtable執行緒安全,但是多執行緒訪問 時同一時間只能有乙個執行緒訪問,效率不高,concurrenthashmap引入了乙個 分段鎖 的概念,具體可以理解為把乙個大的map拆分成n個小的hashtable,根據key.hashcode 來決定把k...