在集合框架里,想必大家都用过ArrayList和LinkedList,ArrayList和ArrayBlockingQueue一样,内部基于数组来存放元素,而LinkedBlockingQueue则和LinkedList一样,内部基于链表来存放元素。
队列常见的出队和入队方法
根据下面代码看下ArrayBlockingQueue的源码
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(20);
queue.put("element");//阻塞方法
String element = queue.take();//阻塞方法
put 方法
public void put(E e) throws InterruptedException {
checkNotNull(e);
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();//获取锁,如果interrupt,直接抛出异常
try {
while (count == items.length)
notFull.await();//队列满了,阻塞等待被唤醒
enqueue(e);//入队
} finally {
lock.unlock();//释放锁
}
}
private void enqueue(E x) {
final Object[] items = this.items;
items[putIndex] = x;
if (++putIndex == items.length)//如果入队下标已满,重置putIndex
putIndex = 0;
count++;//队列总数+1
notEmpty.signal();//唤醒取队列阻塞的线程
}
take 方法
public E take() throws InterruptedException {
final ReentrantLock lock = this.lock;
lock.lockInterruptibly();//获取锁,如果interrupt,直接抛出异常
try {
while (count == 0)
notEmpty.await();//队列空了,阻塞等待被唤醒
return dequeue();//出队
} finally {
lock.unlock();//释放锁
}
}
private E dequeue() {
final Object[] items = this.items;
@SuppressWarnings("unchecked")
E x = (E) items[takeIndex];
items[takeIndex] = null;
if (++takeIndex == items.length)//如果出队下标已满,重置takeIndex
takeIndex = 0;
count--;//总数减1
//迭代器有关
if (itrs != null)
itrs.elementDequeued();
notFull.signal();//唤醒入队列阻塞的线程
return x;
}
取队列的非阻塞方法poll 方法
public E poll() {
final ReentrantLock lock = this.lock;
lock.lock();
try {
return (count == 0) ? null : dequeue();
} finally {
lock.unlock();
}
}
其他方法类似。
ArrayBlockingQueue和LinkedBlockingQueue
原文:https://www.cnblogs.com/dyg0826/p/11276493.html