ArrayBlockingQueue簡介

原文鏈接:http://cxis.me/2016/05/29/ArrayBlockingQueue%E7%AE%80%E4%BB%8B/

  1. ArrayBlockingQueue基於數組,先進先出,從尾部插入到隊列,從頭部開始返回。
  2. 線程安全的有序阻塞隊列,內部通過“互斥鎖”保護競爭資源。
  3. 指定時間的阻塞讀寫
  4. 容量可限制

定義

ArrayBlockingQueue繼承AbstractQueue,實現了BlockingQueue,Serializable接口,內部元素使用Object[]數組保存。初始化時候需要指定容量ArrayBlockingQueue(int capacity),ArrayBlockingQueue默認會使用非公平鎖。

ArrayBlockingQueue只使用一把鎖,造成在存取兩種操作時會競爭同一把鎖,而使得性能相對低下。

add(E)方法和offer(E)

調用父類中的add方法,查看源碼可知父類中的add方法是調用offer方法實現,所以查看offer方法源碼,如下:

public boolean offer(E e) {
    //檢查元素不爲null
    checkNotNull(e);
    //加鎖,獨佔鎖保護競態資源。
    final ReentrantLock lock = this.lock;
    lock.lock();
    try {
        //隊列已滿,返回false
        if (count == items.length)
            return false;
        else {
            //插入元素,返回true
            insert(e);
            return true;
        }
    } finally {
        //釋放鎖
        lock.unlock();
    }
}

insert源碼如下:

private void insert(E x) {
    //將元素添加到隊列中
    items[putIndex] = x;
    //putIndex表示下一個被添加元素的索引,設置下一個被添加元素的索引,若隊列滿了,就設置下一個被添加元素索引爲0
    putIndex = inc(putIndex);
    //隊列的元素數加1
    ++count;
    //喚醒notEmpty上的等待線程,也就是取元素的線程。
    notEmpty.signal();
}

take()方法

public E take() throws InterruptedException {
    //獲取獨佔鎖,加鎖,線程是中斷狀態的話會拋異常
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try {
        //隊列爲空,會一直等待
        while (count == 0)
            notEmpty.await();
        //取元素的方法
        return extract();
    } finally {
        //釋放鎖
        lock.unlock();
    }
}
private E extract() {
    final Object[] items = this.items;
    E x = this.<E>cast(items[takeIndex]);
    //取完之後,刪除元素
    items[takeIndex] = null;
    //設置下一個被取出的元素索引,若是最後一個元素,下一個被取出的元素索引爲0
    takeIndex = inc(takeIndex);
    //元素數減1
    --count;
    //喚醒添加元素的線程
    notFull.signal();
    return x;
}

源碼分析

jdk1.7.0_71

//隊列元素
final Object[] items;
//下次被take,poll,remove的索引
int takeIndex;
//下次被put,offer,add的索引
int putIndex;
//隊列中元素的個數
int count;
//保護所有訪問的主鎖
final ReentrantLock lock;
//等待take鎖,讀線程條件
private final Condition notEmpty;
//等待put鎖,寫線程條件
private final Condition notFull;

ArrayBlockingQueue(int capacity) 給定容量和默認的訪問規則初始化

public ArrayBlockingQueue(int capacity){}

ArrayBlockingQueue(int capacity, boolean fair)知道你跟容量和訪問規則

//fair爲true,在插入和刪除時,線程的隊列訪問會阻塞,並且按照先進先出的順序,false,訪問順序是不確定的
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();
    }

ArrayBlockingQueue(int capacity, boolean fair,Collection

public ArrayBlockingQueue(int capacity, boolean fair,
                              Collection<? extends E> c) {}

add(E e) 添加元素到隊列末尾,成功返回true,隊列滿了拋異常IllegalStateException

public boolean add(E e) {
        return super.add(e);
    }

offer(E e)添加元素到隊列末尾,成功返回true,隊列滿了返回false

public boolean offer(E e) {}

put(E e) 添加元素到隊列末尾,隊列滿了,等待.

public void put(E e) throws InterruptedException {}

offer(E e, long timeout, TimeUnit unit)添加元素到隊列末尾,如果隊列滿了,等待指定的時間

public boolean offer(E e, long timeout, TimeUnit unit){}

poll() 移除隊列頭

public E poll() {}

take() 移除隊列頭,隊列爲空的話就等待

public E take() throws InterruptedException {}

poll(long timeout, TimeUnit unit)移除隊列頭,隊列爲空,等待指定的時間

public E poll(long timeout, TimeUnit unit) throws InterruptedException {}

peek()返回隊列頭,不刪除

public E peek() {}

size()

public int size(){}

remainingCapacity() 返回無阻塞情況下隊列能接受容量的大小

public int remainingCapacity() {}

remove(Object o)從隊列中刪除元素

public boolean remove(Object o) {}

contains(Object o) 是否包含元素

public boolean contains(Object o) {}

toArray()

public Object[] toArray(){}

toArray(T[] a)

public <T> T[] toArray(T[] a) {}

toString()

public String toString(){}

clear()

public void clear(){}

drainTo(Collection

public int drainTo(Collection<? super E> c) {}

drainTo(Collection

public int drainTo(Collection<? super E> c, int maxElements) {}

iterator() 返回一個迭代器

public Iterator<E> iterator() {
        return new Itr();
    }

參考

http://www.jianshu.com/p/9a652250e0d1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章