本文参考https://www.jianshu.com/p/7b2f1fa616c6,对于BlockingQueue进行复述.
BlockingQueue,阻塞队列, 是基于ReentrentLock,通常能够在线程池中看见.
在Java中, BlockingQueue是一个接口,可以由ArrayBlockingQueue和LinkedBlockingQueue来实现.
BlockingQueue中入队和出队的接口.
入队:
offer(E e): 如果队列没满, 则插入, 如果满了, 则return false, 不会造成阻塞.
put(E e): 如果队列满了, 一直阻塞, 直到不满或者被线程中断.
offer(E e, long timeout, TimeUnit unit): 造成阻塞,直到被唤醒,等待超时,当前线程被中断。
LinkedBlockingQueue()
![](https://img.haomeiwen.com/i12624636/18fff00e028e74e2.png)
单向链表, 无限内存, 一把入锁, 一把出锁, 因此可以同时出队入队. 存AtomicInteger来表示Size, 轻量级确保线程安全. 每个节点前半部分表示封装数据x,后面指向下一个引用. 用condition来排等待锁
![](https://img.haomeiwen.com/i12624636/bb5cc0f7bd4d6773.png)
Put方法简介:
如果没满,在condition队列中的线程就会被按顺序释放,获取put锁然后进行enqueue, 直到满了为止.
如果满了, 线程会被设为await()然后放入condition的等待队列中。
Take方法简介: 当队列为空时等待, 当取完发现还有元素可以拿的时候,通知其他等待的take,当队列为空时,唤醒所有的put线程.
当队列空时, 放到等待队列中,
Remove方法简介: 获取两把锁, 遍历,如果发现存在,就删除,如果不存在就return false. 尽量不使用remove() (因为获取两把锁的效率低,而使用size(), 这样比较快))
ArrayBlockingQueue:
一个对象数组+一把锁+两个条件
入队与出队都用同一把锁
在只有入队高并发或出队高并发的情况下,因为操作数组,且不需要扩容,性能很高
采用了数组,必须指定大小,即容量有限
网友评论