一、背景
想起前两年被问到阻塞队列怎么选,有界是必然的, ArrayBlockingQueue、LinkedBlockingQueue怎么选呢。
二、打开源码看看
ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(3);
LinkedBlockingQueue linkedBlockingQueue = new LinkedBlockingQueue(3);
arrayBlockingQueue.put(1);
arrayBlockingQueue.take();
linkedBlockingQueue.put(1);
linkedBlockingQueue.take();
点击方法发现第一个用一个锁,第二两个锁
//LinkedBlockingQueue
private final ReentrantLock takeLock = new ReentrantLock();
private final ReentrantLock putLock = new ReentrantLock();
得出结论,第二个吞吐量高,因为进队列和出队列相互没影响。
三、知识拓展
1、阻塞队列是怎么阻塞住呢?比如队列满了还往里面放是咋处理的?
while (count.get() == capacity) {
notFull.await();
}
notFull.await();会将当前线程放到Condition等待队列中
其实用的还是下列的方法
LockSupport.park(this);
在出队列中必然有一个 LockSupport.unpark(node.thread);
notEmpty.signal();
//一直点点
LockSupport.unpark(node.thread);
2、其他的阻塞队列有那些呢?这里看下线程池创建工具中的另外两个吧
Executors.newCachedThreadPool();//核心线程0 最大线程Integer.MAX_VALUE
Executors.newFixedThreadPool(2);
Executors.newScheduledThreadPool(3);//核心1 最大1
Executors.newSingleThreadExecutor();
newCachedThreadPool使用的是SynchronousQueue;(同步队列)
newScheduledThreadPool使用的是DelayedWorkQueue;(延时队列)