最近学习了 BlockingQueue, 发现 java 的 BlockingQueue 并不是每一个实现都按照 BlockingQueue 的语意来的, 其中有不少坑.
直接上代码吧:
1, 关于 PriorityBlockingQueue, 以下代码运行结果是什么 (答案往下拉)?
- BlockingQueue<Integer> queue = new PriorityBlockingQueue<>(2);
- queue.put(9);
- queue.put(1);
- queue.put(8);
- System.out.println("queue.size() =" + queue.size());
- System.out.println("queue.take() =" + queue.take());
- System.out.println("queue =" + queue);
2, 关于 SynchronousQueue, 以下代码运行结果是什么 (答案往下拉)?
- BlockingQueue<Integer> queue = new SynchronousQueue<>();
- System.out.println("queue.offer(1) =" + queue.offer(1));
- System.out.println("queue.offer(2) =" + queue.offer(2));
- System.out.println("queue.offer(3) =" + queue.offer(3));
- System.out.println("queue.size =" + queue.size());
- System.out.println("queue.take() =" + queue.take());
3, 总体测试, 以下代码运行结果是什么 (答案往下拉)?
- offer(new ArrayBlockingQueue<>(2));
- offer(new LinkedBlockingQueue<>(2));
- offer(new PriorityBlockingQueue<>(2));
- offer(new SynchronousQueue<>());
- private static void offer(BlockingQueue<Integer> queue) throws Exception {
- System.out.println("queue.getClass() =" + queue.getClass().getName());
- System.out.println("queue.offer(1) =" + queue.offer(1));
- System.out.println("queue.offer(2) =" + queue.offer(2));
- System.out.println("queue.offer(3) =" + queue.offer(3));
- System.out.println("queue.size() =" + queue.size());
- System.out.println("queue.take() =" + queue.take());
- }
下面公布答案:
1, 关于 PriorityBlockingQueue 运行结果:
原因:
(1).PriorityBlockingQueue put(Object) 方法不阻塞, 内部直接调用 offer(Object) 方法
(2).PriorityBlockingQueue offer(Object) 方法不限制, 初始化 Queue 大小是没用的
(3).PriorityBlockingQueue 插入对象会做排序, 默认参照元素 Comparable 实现, 或者显示地传递 Comparator(因为传入对象是 Integer, 是默认实现了 Comparable 的)
2, 关于 SynchronousQueue 运行结果
原因:
(1).SynchronousQueue 是无空间, offer 永远返回 false
(2).SynchronousQueue take() 方法会被阻塞, 必须被其他线程显示地调用 put(Object)
如果第 1 题, 第 2 题你的回答都有问题, 那么总结一下, 再看第 3 题的答案吧
3, 总体测试, 运行结果
总体而言, BlockingQueue 最让人想不到的就是 PriorityBlockingQueue 和 SynchronousQueue 了.
总结一下:
(1)ArrayBlockingQueue: 是一个基于数组结构的有界阻塞队列, FIFO(先进先出).
(2)LinkedBlockingQueue: 一个基于链表结构的阻塞队列, 此队列按 FIFO (先进先出) 排序元素, 吞吐量通常要高于 ArrayBlockingQueue, 静态工厂方法 Executors.newFixedThreadPool() 使用了这个队列.
(3)SynchronousQueue: 一个不存储元素的阻塞队列. 每个插入操作必须等到另一个线程调用移除操作, 否则插入操作一直处于阻塞状态, 吞吐量通常要高于 LinkedBlockingQueue, 静态工厂方法 Executors.newCachedThreadPool() 使用了这个队列.
(4)PriorityBlockingQueue: 一个具有优先级的无限阻塞队列.
本文有参考小马哥的讲课.
来源: https://www.cnblogs.com/klbc/p/11384664.html