介绍
LinkedBlockingQueue实现BlockingQueue接口.
JDK中位置:java.util.concurrent包下,该包为并发包,同样LinkedBlockingQueue自身实现了并发处理,使用的是存取锁的方式.
自身还实现了读写分离锁,真正高效并发。
下面直接切入源码.
构造器
默认构造器没有参数
public LinkedBlockingQueue() {
this(Integer.MAX_VALUE);//默认长度
}
指定长度构造器
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;
}