LinkedBlockingQueue和LinkedBlockingDeque基本上大部分特性是相同的。
注意:所有代码源码都是LinkedBlockingQueue的。
特点:
- 都继承于AbstractQueue并实现BlockingQueue,说明有Queue的一些特性例如FIFO和一些方法。
- 两个都是链表结构且结构可变(动态数组),最大容量2^31-1。
- 两个都是队列只不过前者只能一端出一端入(尾先进头先出FIFO),后者则可以两端同时出入(后者方法名有提示哪里进哪里出,如果没有方法名提示last还是first那其实和前者方法一样的)。
- 两个都是通过ReentrantLock实现锁,前者两个锁后者一个锁。所以是线程安全的。
- 两个都是利用Condition实现队列的阻塞等待,唤醒。
一:LinkedBlockingQueue介绍
1:LinkedBlockingQueue是一个基于链表实现的阻塞队列,默认情况下,该阻塞队列的大小为Integer.MAX_VALUE
,由于这个数值特别大,所以 LinkedBlockingQueue 也被称作无界队列,代表它几乎没有界限,队列可以随着元素的添加而动态增长,但是如果没有剩余内存,则队列将抛出OOM错误。所以为了避免队列过大造成机器负载或者内存爆满的情况出现,我们在使用的时候建议手动传一个队列的大小。
2:LinkedBlockingQueue内部由单链表实现,只能从head取元素,从tail添加元素。LinkedBlockingQueue采用两把锁的锁分离技术实现入队出队互不阻塞,添加元素和获取元素都有独立的锁,也就是说LinkedBlockingQueue是读写分离的,读写操作可以并行执行。
二:LinkedBlockingQueue使用
//指定队列的大小创建有界队列
LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>(100);
//无界队列
LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>();//拿无界队列举例操作一些方法
LinkedBlockingQueue<Integer> linkedBlockingQueue = new LinkedBlockingQueue<>();//add() 里面本质也是用的offer()新增的元素linkedBlockingQueue.add(1);linkedBlockingQueue.offer(211);linkedBlockingQueue.add(5);Arrays.stream(linkedBlockingQueue.toArray()).forEach(a->{System.out.println("LinkedBlockingQueue toArray foreach:"+a);});/*** LinkedBlockingQueue toArray foreach:1* LinkedBlockingQueue toArray foreach:211* LinkedBlockingQueue toArray foreach:5*///从头部获得存放时间最长的元素Integer peek1 = linkedBlockingQueue.peek();System.out.println("LinkedBlockingQueue peek:"+peek1);//LinkedBlockingQueue peek:1//判断元素是否存在boolean contains = linkedBlockingQueue.contains(211);System.out.println("LinkedBlockingQueue contains:"+contains);//LinkedBlockingQueue contains:true//从头部取出存放时间最长的元素Integer poll1 = linkedBlockingQueue.poll();System.out.println("LinkedBlockingQueue poll:"+poll1);//LinkedBlockingQueue poll:1Arrays.stream(linkedBlockingQueue.toArray()).forEach(a->{System.out.println("LinkedBlockingQueue poll后 toArray foreach:"+a);});/*** LinkedBlockingQueue poll后 toArray foreach:211* LinkedBlockingQueue poll后 toArray foreach:5*///FIFO 删除头部最早进