1. 程式人生 > >【多執行緒】初步瞭解java多執行緒安全的容器類CopyOnWriteArrayList

【多執行緒】初步瞭解java多執行緒安全的容器類CopyOnWriteArrayList

通常我們理解上,執行緒安全的容器類一般指Vector、HashTable等,但在進一步瞭解後,其實真正意義上的執行緒安全沒有那麼簡單。

執行緒安全實際上分為多個級別:

(1)不可變

不可變類,典型例子是常用的String、Integer、Long等,作為不可變類,任何一個執行緒都改變不了它們的值,要改變除非新建立一個,其中某些表面上進行“改變”的方法,實際上都是返回一個新的物件(String類要注意字串常量池的問題)。

因此,這些不可變物件不需要任何同步手段就可以直接在多執行緒環境下使用。

(2)絕對執行緒安全

不管執行時環境如何,呼叫者都不需要額外的同步措施的一些類。通常來說,要做到這一點通常需要付出許多額外的代價。Java中通常意義上標註執行緒安全的類,實際上絕大多數都不是執行緒安全的。實際上絕對執行緒安全的類,就要提到一個概念“併發容器”,比方說CopyOnWriteArrayList、CopyOnWriteArraySet

(3)相對執行緒安全

相對執行緒安全也就是我們通常意義上所說的執行緒安全,像Vector這種,add、remove方法都是原子操作,不會被打斷,但也僅限於此,如果有個執行緒在遍歷某個Vector、有個執行緒同時在add這個Vector,99%的情況下都會出現ConcurrentModificationException,也就是fail-fast機制。

(4)執行緒非安全

如常用的ArrayList、LinkedList、HashMap等

容器實際上也分為以下幾大類,注意“同步”和“併發”的區別:

同步容器類:在方法上使用了synchronized關鍵詞
1.Vector
2.HashTable

併發容器:使用更為複雜的方法保證執行緒安全性
3.ConcurrentHashMap:分段
4.CopyOnWriteArrayList:寫時複製
5.CopyOnWriteArraySet:寫時複製

Queue:
6.ConcurrentLinkedQueue:是使用非阻塞的方式實現的基於連結節點的無界的執行緒安全佇列,效能非常好。
(java.util.concurrent.BlockingQueue 介面代表了執行緒安全的佇列。)
7.ArrayBlockingQueue:基於陣列的有界阻塞佇列
8.LinkedBlockingQueue:基於連結串列的有界阻塞佇列。
9.PriorityBlockingQueue:支援優先順序的無界阻塞佇列,即該阻塞佇列中的元素可自動排序。預設情況下,元素採取自然升序排列
10.DelayQueue:一種延時獲取元素的無界阻塞佇列。
11.SynchronousQueue:不儲存元素的阻塞佇列。每個put操作必須等待一個take操作,否則不能繼續新增元素。內部其實沒有任何一個元素,容量是0

Deque:
(Deque介面定義了雙向佇列。雙向佇列允許在佇列頭和尾部進行入隊出隊操作。)
12.ArrayDeque:基於陣列的雙向非阻塞佇列。
13.LinkedBlockingDeque:基於連結串列的雙向阻塞佇列。

Sorted容器:
14.ConcurrentSkipListMap:是TreeMap的執行緒安全版本
15.ConcurrentSkipListSet:是TreeSet的執行緒安全版本