- Queue 接口
优先级队列用二叉树排序.
分类
阻塞,是否有界
用的是ReentrantLock + Condition+CAS 来完成锁和线程阻塞唤醒机制
-
ArrayBlockingQueue
-
LinkedBlockingQueue
对比:
- SynchronousQueue ,PriorityBlockingQueue 优先级队列 ,DelayQueue 延迟队列
用的都是Queue的结构
1. add() 添加数据 成功返回true,满了抛出异常 --- 注意会抛异常
public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
Screen Shot 2022-04-22 at 11.37.20 PM.png
- 有可能出现取不到的场景,又不想干等着,所以可以设置超时时间.
offer(E e,long timeout,TimeUnit unit),超时则返回false.
总结
Screen Shot 2022-04-22 at 11.39.59 PM.png所以很多都是用 poll,take, offer等
take不能刹车,一直等。 poll可以刹车,有阻塞时间.
LockSupport.parkNanos() 用的是LockSupport的api,可以指定park的时长.
Lock. lockInterruptibly()
比对
ArrayBlockingQueue 有界
LinkedBlockingQueue,无界
PriorityBlockingQueue,优先级排序无界阻塞队列
Array: 初始就分配好了,额外空间开销小
Linked: 额外Node开销,长时间处理大批量数据时,GC压力大
private final ReentrantLock takeLock = new ReentrantLock();
LinkedBlockingQueue:
2把锁,读锁和写锁,生产和消费并行执行,效率大大提升.
/** Wait queue for waiting takes */
private final Condition notEmpty = takeLock.newCondition();
/** Lock held by put, offer, etc */
private final ReentrantLock putLock = new ReentrantLock();
ArrayBlockingQueue ,读写就一把锁,效率低
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();
}
网友评论