最近学习了 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:一个具有优先级的无限阻塞队列。

本文有参考小马哥的讲课。

记录 Java 的 BlockingQueue 中的一些坑的更多相关文章

  1. 需求:一个页面中需要用到多个字典数据。用于下拉选项,同时,需要将其保存为json格式。以便于key,value的相互转换。记录在实现过程中踩的坑

    本文涉及到的知识: Promise,all()的使用 js处理机制 reduce的用法 map的用法 同步异步 需求: 一个页面中需要用到多个字典数据.用于下拉选项,同时,需要将其保存为json格式. ...

  2. maven build和push image中遇到的坑(学习过程记录)

    最近在做jenkins的持续集成构建,其中一项是要实现docker容器化部署.项目本身是maven项目,我对于maven和docker都没有什么认知基础,于是求助百度和官网,从头开始啃起.遇到了不少的 ...

  3. java中的那些坑

    最近准备换工作,为了少让人家鄙视,就要狠狠地藐视这些面试题目.找了本电子书,发了有好多坑,都是特别简单,但是很少有人做对的题目.面对这样的题目,我却有一种兴奋的感觉,也许是因为一直做着重复的工作没有新 ...

  4. Java表达式中的那些坑

    [1]您确定真正了解后缀表达式与前缀表达式的区别吗? public class IncrementDemo{ public static void main(String[] args) { int ...

  5. Java面试中遇到的坑【填坑篇】

    看到大家对上篇<Java面试中遇到的坑>一文表现出强力的关注度,说明大家确实在面试中遇到了类似的难题.大家在文章留言处积极留言探讨面试中遇到的问题,其中几位同学还提出了自己的见解,我感到非 ...

  6. Java并发编程中线程池源码分析及使用

    当Java处理高并发的时候,线程数量特别的多的时候,而且每个线程都是执行很短的时间就结束了,频繁创建线程和销毁线程需要占用很多系统的资源和时间,会降低系统的工作效率. 参考http://www.cnb ...

  7. Netty中的那些坑

    Netty中的那些坑(上篇) 最近开发了一个纯异步的redis客户端,算是比较深入的使用了一把netty.在使用过程中一边优化,一边解决各种坑.儿这些坑大部分基本上是Netty4对Netty3的改进部 ...

  8. Java SE1.6中的Synchronized

    1 引言 在多线程并发编程中Synchronized一直是元老级角色,很多人都会称呼它为重量级锁,但是随着Java SE1.6对Synchronized进行了各种优化之后,有些情况下它并不那么重了,本 ...

  9. andriod8.1.0源码编译中的一个坑-package com.sun.javadoc does not exist

    这里记录编译过程中的一个坑!!! 编译过程中出现了下面的报错 external/doclava/src/com/google/doclava/ClassInfo.java:20: error: pac ...

随机推荐

  1. jekyll搭建个人博客2

    目录 个性化 jekyll目录结构 修改个人信息 修改头像 修改背景颜色 关于头像的效果 图片问题 域名 个性化 jekyll目录结构 个性化就是要对文件内容作出修改,使得博客外观发生变化,在修改文件 ...

  2. 使用flink Table &Sql api来构建批量和流式应用(3)Flink Sql 使用

    从flink的官方文档,我们知道flink的编程模型分为四层,sql层是最高层的api,Table api是中间层,DataStream/DataSet Api 是核心,stateful Stream ...

  3. word 2010 页眉 http://jingyan.baidu.com/article/a65957f4b0208624e77f9b55.html

    word 2010 页眉 http://jingyan.baidu.com/article/a65957f4b0208624e77f9b55.html

  4. 调用另一个进程,createprocess返回值正确,但被调进程连入口函数都没进入。

    1.单独运行被调进程(提示atl不匹配). 2.编译选项设置为不依赖atl即可. 3.启发:能单独测试的,先单独测试.

  5. 洛谷P2299 Mzc和体委的争夺战 题解

    题目 题目描述 mzc家很有钱(开玩笑),他家有n个男家丁(做过前三弹的都知道).但如此之多的男家丁吸引来了我们的体委(矮胖小伙),他要来与mzc争夺男家丁. mzc很生气,决定与其决斗,但cat的体 ...

  6. 个人永久性免费-Excel催化剂功能第50波-批量打印、导出PDF、双面打印功能

    在倡导无纸化办公的今天,是否打印是一个碍眼的功能呢,某些时候的确是,但对于数据的留存,在现在鼓吹区块链技术的今天,仍然不失它的核心价值,数据报表.单据打印出来留存,仍然是一种不可或缺的数据存档和防篡改 ...

  7. Excel催化剂开源第29波-在Winform上使用富文本编辑器控件

    富文本编辑器,一般都是BS架构专利一般,好像百度有一个开源的比较出名,但无奈这些都只能用在JS上,在BS网页端开发上使用.像Winform开发的VSTO,只能羡慕的份.和一般Winform上用的Ric ...

  8. C#3.0新增功能06 对象和集合初始值设定项

    连载目录    [已更新最新开发文章,点击查看详细] 使用 C# 可以在单条语句中实例化对象或集合并执行成员分配. 对象初始值设定项 使用对象初始值设定项,你可以在创建对象时向对象的任何可访问字段或属 ...

  9. [leetcode] 22. Generate Parentheses(medium)

    原题 思路: 利用DFS,搜索每一种情况,同时先加"("后加")",保证()匹配正确. 最近开始学习前端,尝试用js来写. const generate = f ...

  10. Cesium 学习(二)所支持的模型数据类型,以及转换

    1.Cesium所支持的模型数据类型 目前所知的有glTF.glb.bgltf等格式的模型数据: 想要了解glTF等的知识可以看一下https://www.cnblogs.com/fuckgiser/ ...