介紹java
LinkedBlockingQueue實現BlockingQueue接口.node
JDK中位置:java.util.concurrent包下,該包爲併發包,一樣LinkedBlockingQueue自身實現了併發處理,使用的是存取鎖的方式.併發
自身還實現了讀寫分離鎖,真正高效併發。less
下面直接切入源碼.this
構造器線程
默認構造器沒有參數接口
public LinkedBlockingQueue() { 隊列
this(Integer.MAX_VALUE);//默認長度 ci
} rem
指定長度構造器
public LinkedBlockingQueue(int capacity) {
if (capacity <= 0) throw new IllegalArgumentException();
this.capacity = capacity;
last = head = new Node<E>(null);
}
存方法
public void put(E e) throws InterruptedException {
if (e == null) throw new NullPointerException();
// Note: convention in all put/take/etc is to preset local var
// holding count negative to indicate failure unless set.
int c = -1;
Node<E> node = new Node(e);
final ReentrantLock putLock = this.putLock;
final AtomicInteger count = this.count;
putLock.lockInterruptibly();//得到put鎖,不能有兩個線程同時存入數據
try {
while (count.get() == capacity) {//判斷隊列是否已滿.若是隊列已滿則一直等待
notFull.await();
}
enqueue(node);//存入隊列尾
c = count.getAndIncrement();//計數器自增
if (c + 1 < capacity)
notFull.signal();
} finally {
putLock.unlock();//釋放put鎖
}
if (c == 0)
signalNotEmpty();
}
取方法
public E take() throws InterruptedException {
E x;
int c = -1;
final AtomicInteger count = this.count;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();//不能同時有兩個線程獲取數據
try {
while (count.get() == 0) {//判斷隊列是否爲空.若是爲空則一直循環等待
notEmpty.await();
}
x = dequeue();//取出隊列頭
c = count.getAndDecrement();//計數器自減
if (c > 1)
notEmpty.signal();
} finally {
takeLock.unlock();//釋放tack鎖
}
if (c == capacity)
signalNotFull();
return x;
}