併發場景下的數據結構

數據強、弱一致性:
嚴格一致性(強一致性):所有的讀寫操作都按照全局時鐘下的順序執行,且任何時刻線程讀取到的緩存數據都是一樣的,Hashtable 就是嚴格一致性;
順序一致性:多個線程的整體執行可能是無序的,但對於單個線程而言執行是有序的,要保證任何一次讀都能讀到最近一次寫入的數據,volatile 可以阻止指令重排序,所以修飾的變量的程序屬於順序一致性;
弱一致性:不能保證任何一次讀都能讀到最近一次寫入的數據,但能保證最終可以讀到寫入的數據,單個寫鎖 + 無鎖讀,就是弱一致性的一種實現。

MAP容器
HashMap 
非線程安全
原因:JDK1.7之前,併發場景可能出現死循環(看過幾篇文章說是在擴容時出現循環列表,JDK1.8之後採用紅黑樹說會出現數據丟失以及不準確(沒遇到,左旋or右旋+查詢+查詢導致?))
HashTable
線程安全
強一致性場景
數據量小時使用
缺:使用Synchronized同步鎖修飾put get remove方法,高併發下有大量鎖競爭
ConcurrentHashMap
線程安全
數據量不是特別大時使用
相比HashTable優點:JDK1.7之前分段鎖,JDK1.8之後先使用Synchronized(但是先使用CAS再升級鎖 JDK1.8優化了Synchronized)
適應場景:統計銷量TOP10
缺:get size 等方法沒有使用鎖,弱一致性。
ConcurrentSkipListMap 
基於TreeMap(單線程使用)的設計原理實現,不過TreeMap使用紅黑樹,其使用跳錶
優點:存取平均時間複雜度O(log(n)),適用於大數據量存取的場景,最常見的是基於跳躍表實現的數據量比較大的緩存。
適用場景:提醒用戶手機卡實時流量不足,先同步用戶實時流量,再通過手機端訂單觸發查詢功能,如果流量不足,就彈出系統通知。數據量千萬級,且存在大量增刪改操作。
特點,用戶量大,併發量高,寫入多於查詢。
List容器
Vector
線程安全
強一致性
基於Synchronized同步鎖實現線程安全
缺點:高併發下,讀遠大學寫,大量鎖競爭
CopyOnWriteArrayList
線程安全(寫操作修改副本使用Synchronized)
讀操作無鎖,寫操作使用新副本,讀寫分離。
適用場景:大量讀,少量改。例:黑白名單
Queue容器
ConcurrentLinkedQueue
線程安全
無鎖 使用CAS
使用場景:
1.寫多讀少,該隊列基於鏈表實現,新增和刪除元素性能較高(應該是尾部和頭部)
2.寫操作使用cas操作,性能較高。
3.單生產者,多消費者
缺點:
鏈表無界,容易造成大量內存使用,甚至內存溢出,需要控制容量。
LinkedTransferQueue
一個由鏈表結構組成的無界阻塞TransferQueue隊列。相對於其他阻塞隊列,LinkedTransferQueue多了tryTransfer和transfer方法。
ArrayBlockingQueue(一把全局鎖)
一個基於數組結構實現的有界阻塞隊列,按 FIFO(先進先出)原則對元素進行排序,使用 ReentrantLock、Condition 來實現線程安全;
LinkedBlockingQueue
存取兩把鎖
一個基於鏈表結構實現的阻塞隊列,同樣按 FIFO (先進先出) 原則對元素進行排序,使用 ReentrantLock、Condition 來實現線程安全,吞吐量通常要高於 ArrayBlockingQueue;
disruptor

PriorityBlockingQueue:
一個具有優先級的無限阻塞隊列,基於二叉堆結構實現的無界限(最大值 Integer.MAX_VALUE - 8)阻塞隊列,隊列沒有實現排序,但每當有數據變更時,都會將最小或最大的數據放在堆最上面的節點上,該隊列也是使用了 ReentrantLock、Condition 實現的線程安全;
SynchronousQueue
一個不存儲多個元素的阻塞隊列,每次進行放入數據時, 必須等待相應的消費者取走數據後,纔可以再次放入數據,該隊列使用了兩種模式來管理元素,一種是使用先進先出的隊列,一種是使用後進先出的棧,使用哪種模式可以通過構造函數來指定。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章