java.util.concurrent系列之--ConcurrentLinkedQueue

1、ConcurrentLinkedQueue介紹

ConcurrentLinkedQueue是線程安全的隊列,它適用於「高併發」的場景。它是一個基於連接節點的無界線程html

安全隊列,按照 FIFO(先進先出)原則對元素進行排序。隊列元素中不能夠放置null元素(內部實現的特殊java

節點除外)。數組

2、ConcurrentLinkedQueue原理和數據結構

ConcurrentLinkedQueue的數據結構,以下圖所示:安全

輸入圖片說明

說明:數據結構

1. ConcurrentLinkedQueue繼承於AbstractQueue。

2. ConcurrentLinkedQueue內部是經過鏈表來實現的。它同時包含鏈表的頭節點head和尾節點tail。

ConcurrentLinkedQueue按照 FIFO(先進先出)原則對元素進行排序。元素都是從尾部插入到鏈表,從頭多線程

部開始返回。併發

3. ConcurrentLinkedQueue的鏈表Node中的next的類型是volatile,並且鏈表數據item的類型也是

volatile。關於volatile,咱們知道它的語義包含:「即對一個volatile變量的讀,老是能看到(任意線程)對這ide

個volatile變量最後的寫入」。ConcurrentLinkedQueue就是經過volatile來實現多線程對競爭資源的互斥訪高併發

問的。線程

3、ConcurrentLinkedQueue原理和數據結構

// 建立一個最初爲空的 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)

4、ConcurrentLinkedQueue示例

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異常。

5、轉載地址

http://www.cnblogs.com/skywang12345/p/3498995.html

相關文章
相關標籤/搜索