初学者java入门基础知识 java双端队列原理( 三 )


非阻塞队列ConcurrentLinkedQueue 是一个基于链接节点的无界线程安全队列 , 它采用先进先出的规则对节点进行排序 , 当我们添加一个元素的时候 , 它会添加到队列的尾部;当我们获取一个元素时 , 它会返回队列头部的元素 。它的入队和出队操作均利用 CAS(Compare And Set)更新 , 这样允许多个线程并发执行 , 并且不会因为加锁而阻塞线程 , 使得并发性能更好 。ConcurrentLinkedQueue 使用示例:
ConcurrentLinkedQueue concurrentLinkedQueue = new ConcurrentLinkedQueue();concurrentLinkedQueue.add("Dog");concurrentLinkedQueue.add("Cat");while (!concurrentLinkedQueue.isEmpty()) {System.out.println(concurrentLinkedQueue.poll());}执行结果:

Dog
Cat
可以看出不管是阻塞队列还是非阻塞队列 , 使用方法都是类似的 , 区别是底层的实现方式 。
优先级队列PriorityQueue 一个基于优先级堆的无界优先级队列 。优先级队列的元素按照其自然顺序进行排序 , 或者根据构造队列时提供的 Comparator 进行排序 , 具体取决于所使用的构造方法 。优先级队列不允许使用 null 元素 。PriorityQueue 代码使用示例:
Queue<Integer> priorityQueue = new PriorityQueue(new Comparator<Integer>() {@Overridepublic int compare(Integer o1, Integer o2) {// 非自然排序 , 数字倒序return o2 - o1;}});priorityQueue.add(3);priorityQueue.add(1);priorityQueue.add(2);while (!priorityQueue.isEmpty()) {Integer i = priorityQueue.poll();System.out.println(i);}程序执行的结果是:
3
2
1
PriorityQueue 注意的点:
  1. PriorityQueue 是非线程安全的 , 在多线程情况下可使用 PriorityBlockingQueue 类替代;
  2. PriorityQueue 不允许插入 null 元素 。
相关面试题1.ArrayBlockingQueue 和 LinkedBlockingQueue 的区别是什么?答:ArrayBlockingQueue 和 LinkedBlockingQueue 都实现自阻塞队列 BlockingQueue , 它们的区别主要体现在以下几个方面:
  • ArrayBlockingQueue 使用时必须指定容量值 , LinkedBlockingQueue 可以不用指定;
  • ArrayBlockingQueue 的最大容量值是使用时指定的 , 并且指定之后就不允许修改;而 LinkedBlockingQueue 最大的容量为 Integer.MAX_VALUE;
  • ArrayBlockingQueue 数据存储容器是采用数组存储的;而 LinkedBlockingQueue 采用的是 Node 节点存储的 。
2.LinkedList 中 add() 和 offer() 有什么关系?答:add() 和 offer() 都是添加元素到队列尾部 。offer 方法是基于 add 方法实现的 , Offer 的源码如下:
public boolean offer(E e) {return add(e);}3.Queue 和 Deque 有什么区别?答:Queue 属于一般队列 , Deque 属于双端队列 。一般队列是先进先出 , 也就是只有先进的才能先出;而双端队列则是两端都能插入和删除元素 。
4.LinkedList 属于一般队列还是双端队列?答:LinkedList 实现了 Deque 属于双端队列 , 因此拥有 addFirst(E)、addLast(E)、getFirst()、getLast() 等方法 。
5.以下说法错误的是?A:DelayQueue 内部是基于 PriorityQueue 实现的 B:PriorityBlockingQueue 不是先进先出的数据存储方式 C:LinkedBlockingQueue 容量是无限大的 D:ArrayBlockingQueue 内部的存储单元是数组 , 初始化时必须指定队列容量 答:C 题目解析:LinkedBlockingQueue 默认容量是 Integer.MAX_VALUE , 并不是无限大的 , 源码如下图所示:

初学者java入门基础知识 java双端队列原理

推荐阅读