一、 LinkedBlockingQueue介绍
LinkedBlockingQueue是一个基于链表实现的阻塞队列,默认情况下,该阻塞队列的大小为Integer.MAX_VALUE,由于这个数值特别大,所以 LinkedBlockingQueue 也被称作无界队列,代表它几乎没有界限,队列可以随着元素的添加而动态增长,但是如果没有剩余内存,则队列将抛出OOM错误。所以为了避免队列过大造成机器负载或者内存爆满的情况出现,我们在使用的时候建议手动传一个队列的大小。
LinkedBlockingQueue内部由单链表实现,只能从head取元素,从tail添加元素。LinkedBlockingQueue采用两把锁的锁分离技术实现入队出队互不阻塞,添加元素和获取元素都有独立的锁,也就是说LinkedBlockingQueue是读写分离的,读写操作可以并行执行。
二、LinkedBlockingQueue使用
-
申明
1 2 3 4
//指定队列的大小创建有界队列 BlockingQueue<Integer> boundedQueue = new LinkedBlockingQueue<>(100); //无界队列 BlockingQueue<Integer> unboundedQueue = new LinkedBlockingQueue<>();
-
消费
1 2 3 4 5 6 7 8 9 10 11 12 13
@Service @Slf4j public class QueueComsumer { public static BlockingQueue<String> boundedQueue = new LinkedBlockingQueue<>(1000); @SneakyThrows @Async public void comsumer() { while (true) { String str = boundedQueue.take(); log.info("收到消息:{}", str); } } }
-
生产
1 2 3 4 5
@GetMapping("/queue") @IgnoreAuthorize public void getResult(String s) { boundedQueue.offer(s); }
三、常用方法
LinkedBlockingQueue添加元素的方法有三个:add、put、offer。且都是向队列尾部添加元素。
-
add:方法在添加元素的时候,若超出了度列的长度会直接抛出异常。
-
offer:方法添加元素,如果队列已满,直接返回false。
-
put:方法添加元素,如果队列已满,会阻塞直到有空间可以放。
LinkedBlockingQueue移除元素的方法有三个:poll、remove、take。且都是从队列中取出头部元素并从队列中删除。
-
poll: 若队列为空,返回null。
-
take:若队列为空,发生阻塞,等待到有元素。
-
remove::若队列为空,抛出NoSuchElementException异常。
LinkedBlockingQueue可以在构造函数的参数中指定大小,若没有指定大小,则默认大小为Integer.MAX_VALUE。LinkedBlockingQueue的大小不可为null。