1. 程式人生 > >面試--集合(四)併發集合框架阻塞佇列與非阻塞佇列

面試--集合(四)併發集合框架阻塞佇列與非阻塞佇列

java語的框架父類介面是Iterable,從這個介面向下一一進行繼承。

一:集合架構的簡介

1:介面Iterable

主要用於迭代迴圈,僅有一個iterator()方法,通過返回Iterable物件,進行迴圈處理。

2:介面Collection

提供了集合框架最主要,最常用的操作,介面內部提供的主要方法是針對資料的怎刪改查操作。

3:介面list

介面list對Collection介面進行擴充套件,允許資料根據索引位置操作資料,並且內容允許重複。實現類ArrayList可以使陣列有序排序,但不是執行緒安全的,如果想使用執行緒安全的連結串列則可以使用Vector類,Vector類是執行緒安全的。

3:介面set

set也是對Collection進行擴充套件,它的特點是內容不允許重複,排序方式為自然排序,為了防止元素重複的原理使用的是元素重寫hashCode()和equals()方法,set的常用介面是不支援執行緒安全的HashSet.

二:非阻塞佇列

非阻塞佇列的特點是佇列裡面沒有資料時,操作佇列會返回異常或者null,不具有阻塞佇列的優點。常見的非阻塞佇列有:

ConcurrentHashMap,ConcurrentSkipListMap,ConcurrentSkipListSet,ConcurrentLinkedQueue,ConcurrentLinkedDeque,

CopyOnWriteArrayList,CopyOnWriteArraySet.

1:ConcurrentHashMap的使用:

由於HashMap不是執行緒安全的,而HashTable是執行緒安全的,當多個執行緒呼叫iterator()方法返回iterator物件,再呼叫remove()方法時會出現異常,就是不支援Iterator併發的刪除。可以使用ConcurrentHashMap類。

ConcurrentHashMap支援迭代,但是不支援排序,如果排序可以使用LinkedHashMap,LinkedHashMap支援key的順序性,但是不支援併發。

2:ConcurrentSkipListMap的使用:

如果有要安全性又要排序就可以使用ConcurrentSkipListMap。

3:ConcurrentSkipListSet使用

ConcurrentSkipListMap類支援排序而且不允許重複的元素,

4:ConcurrentLinkedQueue的使用:

ConcurrentLinkedQueue類提供了併發環境的佇列操作,

方法poll()當前沒有獲得資料時返回null,如果有資料則移除表頭,並將表頭進行返回,

方法element()當前沒有獲取資料時出現NoSuchElementException異常,如果有資料則返回表頭項,

方法peek()當前沒有獲得發回資料時返回為null,有資料則  不移除表頭,並將表頭進行返回。

5:ConcurrentLinkedDeque的使用:

ConcurrentLinkedQueue僅支援對列頭進行操作,ConcurrentLinkedDeue支援對列頭和列尾雙向操作。

6:CopyOnWriteArrayList的使用:

支援執行緒安全,解決ArrayList執行緒不安全。

7:CopyOnWriteArraySet:

支援執行緒安全,解決hashSet執行緒不安全。

三:阻塞佇列https://blog.csdn.net/stafen1/article/category/6863952

http://ifeve.com/java-blocking-queue/    併發程式設計網

阻塞佇列:如果佇列是空,從佇列取東西會被阻塞進入等待,直到佇列裡添加了元素才會被喚醒。如果是滿的佇列,一樣被阻塞。

JDK7提供了7個阻塞佇列。分別是

  • ArrayBlockingQueue :一個由陣列結構組成的有界阻塞佇列。
  • LinkedBlockingQueue :一個由連結串列結構組成的有界阻塞佇列。
  • PriorityBlockingQueue :一個支援優先順序排序的無界阻塞佇列。
  • DelayQueue:一個使用優先順序佇列實現的無界阻塞佇列。
  • SynchronousQueue:一個不儲存元素的阻塞佇列。
  • LinkedTransferQueue:一個由連結串列結構組成的無界阻塞佇列。
  • LinkedBlockingDeque:一個由連結串列結構組成的雙向阻塞佇列。

1ArrayBlockingQueue

ArrayBlockingQueue是一個用陣列實現的有界阻塞佇列。此佇列按照先進先出(FIFO)的原則對元素進行排序。預設情況下不保證訪問者公平的訪問佇列,所謂公平訪問佇列是指阻塞的所有生產者執行緒或消費者執行緒,當佇列可用時,可以按照阻塞的先後順序訪問佇列,即先阻塞的生產者執行緒,可以先往佇列裡插入元素,先阻塞的消費者執行緒,可以先從佇列裡獲取元素。通常情況下為了保證公平性會降低吞吐量。我們可以使用以下程式碼建立一個公平的阻塞佇列:

1 ArrayBlockingQueue fairQueue = new  ArrayBlockingQueue(1000,true);

訪問者的公平性是使用可重入鎖實現的,程式碼如下:

public ArrayBlockingQueue(int capacity, boolean fair) {
        if (capacity <= 0)
            throw new IllegalArgumentException();
        this.items = new Object[capacity];
        lock = new ReentrantLock(fair);
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
}

LinkedBlockingQueue

LinkedBlockingQueue和ArrayBlockingQueue類似,只不過LInkedBlockingQueue是無界的,也可以定義成一個有界的。

一個用連結串列實現的有界阻塞佇列。此佇列的預設和最大長度為Integer.MAX_VALUE。此佇列按照先進先出的原則對元素進行排序。

PriorityBlockingQueue

PriorityBlockingQueue是一個支援優先順序的無界佇列。預設情況下元素採取自然順序排列,也可以通過比較器comparator來指定元素的排序規則。元素按照升序排列。

SynchronousQueue

SynchronousQueue為非同步佇列,是一個不儲存元素的阻塞佇列。每一個put操作必須等待一個take操作,否則不能繼續新增元素。SynchronousQueue可以看成是一個傳球手,負責把生產者執行緒處理的資料直接傳遞給消費者執行緒。佇列本身並不儲存任何元素,非常適合於傳遞性場景,比如在一個執行緒中使用的資料,傳遞給另外一個執行緒使用,SynchronousQueue的吞吐量高於LinkedBlockingQueue 和 ArrayBlockingQueue。

DelayQueue

DelayQueue是一個支援延時獲取元素的無界阻塞佇列。佇列使用PriorityQueue來實現。佇列中的元素必須實現Delayed介面,在建立元素時可以指定多久才能從佇列中獲取當前元素。只有在延遲期滿時才能從佇列中提取元素。我們可以將DelayQueue運用在以下應用場景:

  • 快取系統的設計:可以用DelayQueue儲存快取元素的有效期,使用一個執行緒迴圈查詢DelayQueue,一旦能從DelayQueue中獲取元素時,表示快取有效期到了。
  • 定時任務排程。使用DelayQueue儲存當天將會執行的任務和執行時間,一旦從DelayQueue中獲取到任務就開始執行,從比如TimerQueue就是使用DelayQueue實現的。

佇列中的Delayed必須實現compareTo來指定元素的順序。比如讓延時時間最長的放在佇列的末尾。

LinkedTransferQueue

LinkedTransferQueue是一個由連結串列結構組成的無界阻塞TransferQueue佇列。相對於其他阻塞佇列LinkedTransferQueue多了tryTransfer和transfer方法。