ConcurrentLinkedQueue是線程安全的隊列,它適用於「高併發」的場景。它是一個基於連接節點的無界線程html
安全隊列,按照 FIFO(先進先出)原則對元素進行排序。隊列元素中不能夠放置null元素(內部實現的特殊java
節點除外)。數組
ConcurrentLinkedQueue的數據結構,以下圖所示:安全
說明:數據結構
ConcurrentLinkedQueue按照 FIFO(先進先出)原則對元素進行排序。元素都是從尾部插入到鏈表,從頭多線程
部開始返回。併發
volatile。關於volatile,咱們知道它的語義包含:「即對一個volatile變量的讀,老是能看到(任意線程)對這ide
個volatile變量最後的寫入」。ConcurrentLinkedQueue就是經過volatile來實現多線程對競爭資源的互斥訪高併發
問的。線程
// 建立一個最初爲空的 ConcurrentLinkedQueue。 ConcurrentLinkedQueue() // 建立一個最初包含給定 collection 元素的 ConcurrentLinkedQueue,按照此 collection 迭代器的遍歷順序來添加元素。 ConcurrentLinkedQueue(Collection<? extends E> c) // 將指定元素插入此隊列的尾部。 boolean add(E e) // 若是此隊列包含指定元素,則返回 true。 boolean contains(Object o) // 若是此隊列不包含任何元素,則返回 true。 boolean isEmpty() // 返回在此隊列元素上以恰當順序進行迭代的迭代器。 Iterator<E> iterator() // 將指定元素插入此隊列的尾部。 boolean offer(E e) // 獲取但不移除此隊列的頭;若是此隊列爲空,則返回 null。 E peek() // 獲取並移除此隊列的頭,若是此隊列爲空,則返回 null。 E poll() // 從隊列中移除指定元素的單個實例(若是存在)。 boolean remove(Object o) // 返回此隊列中的元素數量。 int size() // 返回以恰當順序包含此隊列全部元素的數組。 Object[] toArray() // 返回以恰當順序包含此隊列全部元素的數組;返回數組的運行時類型是指定數組的運行時類型。 <T> T[] toArray(T[] a)
import java.util.*; import java.util.concurrent.*; /* * ConcurrentLinkedQueue是「線程安全」的隊列,而LinkedList是非線程安全的。 * * 下面是「多個線程同時操做而且遍歷queue」的示例 * (01) 當queue是ConcurrentLinkedQueue對象時,程序能正常運行。 * (02) 當queue是LinkedList對象時,程序會產生ConcurrentModificationException異常。 * * @author skywang */ public class ConcurrentLinkedQueueDemo1 { // TODO: queue是LinkedList對象時,程序會出錯。 //private static Queue<String> queue = new LinkedList<String>(); private static Queue<String> queue = new ConcurrentLinkedQueue<String>(); public static void main(String[] args) { // 同時啓動兩個線程對queue進行操做! new MyThread("ta").start(); new MyThread("tb").start(); } private static void printAll() { String value; Iterator iter = queue.iterator(); while (iter.hasNext()) { value = (String) iter.next(); System.out.print(value + ", "); } System.out.println(); } private static class MyThread extends Thread { MyThread(String name) { super(name); } @Override public void run() { int i = 0; while (i++ < 6) { // 「線程名」 + "-" + "序號" String val = Thread.currentThread().getName() + i; queue.add(val); // 經過「Iterator」遍歷queue。 printAll(); } } } }
結果說明:若是將源碼中的queue改爲LinkedList對象時,程序會產生ConcurrentModificationException異常。