BlockingQueue最终会有四种状况,抛出异常、返回特殊值、阻塞、超时,下表总结了这些方法:

抛出异常

特殊值

阻塞

超时

插入

add(e)

offer(e)

put(e)

offer(e, time, unit)

移除

remove()

poll()

take()

poll(time, unit)

检查

element()

peek()

不可用

不可用

BlockingQueue是个接口,有如下实现类:

1. ArrayBlockQueue:一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象必须明确大小,像数组一样。

2. LinkedBlockQueue:一个可改变大小的阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。创建其对象如果没有明确大小,默认值是Integer.MAX_VALUE。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。

3. PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。

4. SynchronousQueue:同步队列。同步队列没有任何容量,每个插入必须等待另一个线程移除,反之亦然

下面使用ArrayBlockQueue来实现之前实现过的生产者消/费者模式,代码如下:

  1. /** 定义一个盘子类,可以放鸡蛋和取鸡蛋 */
  2. public class BigPlate {
  3. /** 装鸡蛋的盘子,大小为5 */
  4. private BlockingQueue<Object> eggs = new ArrayBlockingQueue<Object>(5);
  5. /** 放鸡蛋 */
  6. public void putEgg(Object egg) {
  7. try {
  8. eggs.put(egg);// 向盘子末尾放一个鸡蛋,如果盘子满了,当前线程阻塞
  9. catch (InterruptedException e) {
  10. e.printStackTrace();
  11. }
  12. // 下面输出有时不准确,因为与put操作不是一个原子操作
  13. System.out.println("放入鸡蛋");
  14. }
  15. /** 取鸡蛋 */
  16. public Object getEgg() {
  17. Object egg = null;
  18. try {
  19. egg = eggs.take();// 从盘子开始取一个鸡蛋,如果盘子空了,当前线程阻塞
  20. catch (InterruptedException e) {
  21. e.printStackTrace();
  22. }
  23. // 下面输出有时不准确,因为与take操作不是一个原子操作
  24. System.out.println("拿到鸡蛋");
  25. return egg;
  26. }
  27. /** 放鸡蛋线程 */
  28. static class AddThread extends Thread {
  29. private BigPlate plate;
  30. private Object egg = new Object();
  31. public AddThread(BigPlate plate) {
  32. this.plate = plate;
  33. }
  34. public void run() {
  35. plate.putEgg(egg);
  36. }
  37. }
  38. /** 取鸡蛋线程 */
  39. static class GetThread extends Thread {
  40. private BigPlate plate;
  41. public GetThread(BigPlate plate) {
  42. this.plate = plate;
  43. }
  44. public void run() {
  45. plate.getEgg();
  46. }
  47. }
  48. public static void main(String[] args) {
  49. BigPlate plate = new BigPlate();
  50. // 先启动10个放鸡蛋线程
  51. for(int i = 0; i < 10; i++) {
  52. new Thread(new AddThread(plate)).start();
  53. }
  54. // 再启动10个取鸡蛋线程
  55. for(int i = 0; i < 10; i++) {
  56. new Thread(new GetThread(plate)).start();
  57. }
  58. }
  59. }

阻塞队列BlockingQueue的更多相关文章

  1. Java并发编程-阻塞队列(BlockingQueue)的实现原理

    背景:总结JUC下面的阻塞队列的实现,很方便写生产者消费者模式. 常用操作方法 常用的实现类 ArrayBlockingQueue DelayQueue LinkedBlockingQueue Pri ...

  2. Java并发(十八):阻塞队列BlockingQueue

    阻塞队列(BlockingQueue)是一个支持两个附加操作的队列. 这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用. 阻塞队列常用于生产 ...

  3. spring线程池ThreadPoolTaskExecutor与阻塞队列BlockingQueue

    一: ThreadPoolTaskExecutor是一个spring的线程池技术,查看代码可以看到这样一个字段: private ThreadPoolExecutor threadPoolExecut ...

  4. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

  5. 并发编程-concurrent指南-阻塞队列BlockingQueue

    阻塞队列BlockingQueue,java.util.concurrent下的BlockingQueue接口表示一个线程放入和提取实例的队列. 适用场景: BlockingQueue通常用于一个线程 ...

  6. Java并发指南11:解读 Java 阻塞队列 BlockingQueue

    解读 Java 并发队列 BlockingQueue 转自:https://javadoop.com/post/java-concurrent-queue 最近得空,想写篇文章好好说说 java 线程 ...

  7. 阻塞队列BlockingQueue用法

    多线程环境中,通过队列可以很容易实现数据共享,比如经典的“生产者”和“消费者”模型中,通过队列可以很便利地实现两者之间的数据共享. 假设我们有若干生产者线程,另外又有若干个消费者线程.如果生产者线程需 ...

  8. 阻塞队列BlockingQueue用法(转)

    多线程环境中,通过队列可以很容易实现数据共享,比如经典的“生产者”和“消费者”模型中,通过队列可以很便利地实现两者之间的数据共享. 假设我们有若干生产者线程,另外又有若干个消费者线程.如果生产者线程需 ...

  9. java并发包——阻塞队列BlockingQueue及源码分析

    一.摘要 BlockingQueue通常用于一个线程在生产对象,而另外一个线程在消费这些对象的场景,例如在线程池中,当运行的线程数目大于核心的线程数目时候,经常就会把新来的线程对象放到Blocking ...

随机推荐

  1. Linux如何设置dns

    首先打开dns设置文档 空的dns文档如图所示 键入图片中的文本保存即可设置了自己的dns 保存后推出即可.

  2. 201521123033《Java程序设计》第10周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. answer: 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图 ...

  3. 201521123110《Java程序与设计》第13周学习总结

    1. 本周学习总结 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu.edu.cn,分析返回结果有何不同?为什么会有这样的不同? 时间数据不同 ...

  4. 201521123022 《Java程序设计》 第九周学习总结

    1.本章学习总结 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 Q1.1 截图你的提交结果(出现学号) Q1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何 ...

  5. MyBatis学习(六)MyBatis关联映射之一对多映射

    数据库中一对多通常使用主外键关联,外键应该在多方,即多方维护关系. 下面举一个简单实例来看看MyBatis怎么处理一对多的关系. 1.创建一个项目,导入所需jar包,导入db.properties配置 ...

  6. 关于sping quartz定时执行理解与思考

    转载请注明原创出处,谢谢! 一直以为自己理解spring quartz,忽然最近几天发现自己理解的不对,在4月18号的时候,我执行了一个spring quartz的计划如下: 1 0 0 */3 * ...

  7. angular smart-table组件如何定制化之初步研究

    table表运用在后台管理用得频繁,一般bootstrap的class="table"就能满足样式需求以及分页需求,但是每个产品经理需求不一样,比如说分页:bootstrap分页实 ...

  8. CSV导出大量数据

    $csvname = $csvname . '.csv'; header('Content-Type: application/vnd.ms-excel;charset=GB2312'); heade ...

  9. PHP中isset和empty的区别(最后总结)

    PHP的isset()函数 一般用来检测变量是否设置 格式:bool isset ( mixed var [, mixed var [, ...]] ) 功能:检测变量是否设置 返回值: 若变量不存在 ...

  10. tomcat部署在centos6.8上的乱码问题

    web访问经常会莫名其妙的出现各种乱码问题.按照我自己的理解,设置一个charSet的过滤器,代码如下:import java.io.IOException; import javax.servlet ...