BlockingQueue
|
|
BlockingQueue可以作为多线程的数据共享通道,关键在于“Blocking”。
| 方法 | 描述 |
|---|---|
| boolean add(E e) | 添加成功,返回true;容量满抛出异常 |
| boolean remove(Object o) | 删除成功,返回true;否则返回false |
| boolean offer(E e) | 入队成功,返回true;否则返回false |
| E poll(long timeout, TimeUnit unit) | 出队,返回元素;空队列返回null |
| void put(E e) | 入队,队列满了会等待(Blocking) |
| E take() | 出队,队列为空会等待(Blocking) |
常用的阻塞队列具体类有 ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、LinkedBlockingDeque 等。
ArrayBlockingQueue
|
|
ArrayBlockingQueue是一个基于数组且有界的阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。
属性
内部元素用一个对象数组存储,等待通知机制是通过一个ReentrantLock和两个Condition实现的。
构造函数
|
|
等待
put
当队列满时,需要让压入线程等待在notFull。
take
当队列为空时,当前线程等待在notEmpty。
通知
dequeue
当有元素从队列中被挪走,队列中出现空位时,通知等待入队的线程notFull。
enqueue
当队列中有新元素时,通知等待出队的线程notNull。
LinkedBlockingQueue
|
|
LinkedBlockingQueue是一个使用链表完成队列操作的阻塞队列。链表是单向链表,而不是双向链表。内部采用两把锁放锁和拿锁,所以读写可以同时进行。
属性
内部使用放锁和拿锁,这两个锁实现阻塞,所以元素数量存在竞态条件,这里使用原子类AtomicInteger保证线程安全。
构造方法
|
|
等待和通知
LinkedBlockingQueue和ArrayBlockingQueue底层实现不同,由于有两个锁,在消费数据和插入数据时都有机会唤醒notFull和notEmpty。
ArrayBlockingQueue是将通知放在enqueue()和dequeue中了。