欢迎来我的博客参观,交流:https://endwas.cn
一、前言
我们经常可以在很多地方看到BlockingQueue的声影,最常见的就是在线程池中使用各式的阻塞队列。
在Java中,BlockingQueue是一个接口,它的实现类有ArrayBlockingQueue、DelayQueue、 LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等,它们的区别主要体现在存储
结构上或对元素操作上的不同,但是对于take与put操作的原理,却是类似的,目的都是阻塞存取。
二、阻塞与非阻塞
入队
add(E e):(非阻塞)调用offer但会根据offer结果,如果false抛出 IllegalStateException(“Queue full”)
offer(E e):(非阻塞)如果队列没满,立即返回true; 如果队列满了,立即返回false
put(E e):(阻塞)如果队列满了,一直阻塞,直到队列不满了或者线程被中断
offer(E e, long timeout, TimeUnit unit):在队尾插入一个元素,,如果队列已满,则进入等待,直到出现以下三种情况:
- 被唤醒
- 等待时间超时
- 当前线程被中断
出队
poll():(非阻塞)如果没有元素,直接返回null;如果有元素,出队
remove():(非阻塞)删除队列头元素,如果没有元素,返回false
take():(阻塞)如果队列空了,一直阻塞,直到队列不为空或者线程被中断
poll(long timeout, TimeUnit unit):如果队列不空,出队;如果队列已空且已经超时,返回null;如果队列已空且时间未超时,则进入等待,直到出现以下三种情况:
- 被唤醒
- 等待时间超时
- 当前线程被中断
查看元素
element(): 调用peek(),查看元素,拿到为null,抛出 NoSuchElementException。
peek():查看元素,不去除,如果拿不到则为null。
三、常见队列特点
1. ArrayBlockingQueue
顾名思义数组阻塞队列,内部肯定以数组来做队列元素存储;
- 特点:ArrayBlockingQueue底层是使用一个数组实现队列的,内部使用了一把锁对插入和取出做了限制,即插或者取的操作是原子性
- 容量:需要指定一个大小,创建了无法修改
- 元素:不允许为null的元素插入