并发队列:

在并发队列中,JDK有两套实现:

ConcurrentLinkedQueue:非阻塞式队列

BlockingQueue:阻塞式队列

阻塞式队列非阻塞式队列的区别:

阻塞式队列入列操作的时候,如果超出队列总数,这个时候会进行等待;在出列的时候,如果队列为空,也会等待

非阻塞无论如何都不等待

非阻塞效率更高,但是阻塞使用更广泛

阻塞队列的优点是能够防止队列容器溢出,防止丢失

非阻塞队列:

  1. public class QueueDemo {
  2. public static void main(String[] args) {
  3. ConcurrentLinkedQueue<String> concurrentLinkedQueue = new ConcurrentLinkedQueue<>();
  4. concurrentLinkedQueue.offer("张三");
  5. concurrentLinkedQueue.offer("李四");
  6. concurrentLinkedQueue.offer("王五");
  7. for (int i = 0; i < 4; i++) {
  8. System.out.println(concurrentLinkedQueue.poll());
  9. }
  10. }
  11. }

打印如下:

  1. 张三
  2. 李四
  3. 王五
  4. null

阻塞队列(重要):需要初始化队列总数

  1. public class QueueDemo {
  2. public static void main(String[] args) throws InterruptedException {
  3. BlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
  4. //添加非阻塞式队列
  5. arrayBlockingQueue.offer("张三");
  6. arrayBlockingQueue.offer("李四");
  7. arrayBlockingQueue.offer("王五");
  8. //添加阻塞式队列,等待时间为3s
  9. arrayBlockingQueue.offer("赵六",3, TimeUnit.SECONDS);
  10. System.out.println(arrayBlockingQueue.poll());
  11. System.out.println(arrayBlockingQueue.poll());
  12. System.out.println(arrayBlockingQueue.poll());
  13. System.out.println(arrayBlockingQueue.poll(3,TimeUnit.SECONDS));
  14. }
  15. }

这种情况,等待3秒后打印:张三,李四,王五,再等待3秒后打印:null

换一下代码:

  1. public class QueueDemo {
  2. public static void main(String[] args) throws InterruptedException {
  3. BlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
  4. //添加非阻塞式队列
  5. arrayBlockingQueue.offer("张三");
  6. arrayBlockingQueue.offer("李四");
  7. System.out.println(arrayBlockingQueue.poll());
  8. arrayBlockingQueue.offer("王五");
  9. //添加阻塞式队列,等待时间为3s
  10. arrayBlockingQueue.offer("赵六",3, TimeUnit.SECONDS);
  11. System.out.println(arrayBlockingQueue.poll());
  12. System.out.println(arrayBlockingQueue.poll());
  13. System.out.println(arrayBlockingQueue.poll());
  14. System.out.println(arrayBlockingQueue.poll(3,TimeUnit.SECONDS));
  15. }
  16. }

这种情况,立即打印张三,李四,王五,赵六,等待3秒后打印null

示例:

  1. public class QueueDemo {
  2. public static void main(String[] args) throws InterruptedException {
  3. BlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(3);
  4. //添加非阻塞式队列
  5. boolean success1 = arrayBlockingQueue.offer("张三");
  6. boolean success2 = arrayBlockingQueue.offer("李四");
  7. boolean success3 = arrayBlockingQueue.offer("王五");
  8. //添加阻塞式队列,等待时间为3s
  9. boolean success4 = arrayBlockingQueue.offer("赵六",3, TimeUnit.SECONDS);
  10. System.out.println(success1);
  11. System.out.println(success2);
  12. System.out.println(success3);
  13. System.out.println(success4);
  14. }
  15. }

等待3秒后打印:true,true,true,false;说明赵六没有入列成功

生产者消费者示例:

下面模拟一个生产者消费者的例子,以便于更好地理解:

生产者线程存一个队列,消费者线程取一个队列,多线程中可以采用等待唤醒机制,在这里采用并发队列实现

  1. package org.dreamtech;
  2.  
  3. import java.util.concurrent.BlockingQueue;
  4. import java.util.concurrent.LinkedBlockingQueue;
  5. import java.util.concurrent.TimeUnit;
  6. import java.util.concurrent.atomic.AtomicInteger;
  7.  
  8. /**
  9. * 生产者线程,负责添加队列
  10. */
  11. class ProducerThread implements Runnable {
  12.  
  13. private BlockingQueue<String> blockingQueue;
  14.  
  15. private volatile boolean FLAG = true;
  16.  
  17. private AtomicInteger atomicInteger = new AtomicInteger();
  18.  
  19. ProducerThread(BlockingQueue<String> blockingQueue) {
  20. this.blockingQueue = blockingQueue;
  21. }
  22.  
  23. @Override
  24. public void run() {
  25. try {
  26. System.out.println("---生产者线程启动成功---");
  27. while (FLAG) {
  28. String data = atomicInteger.incrementAndGet() + "";
  29. boolean success = blockingQueue.offer(data, 2, TimeUnit.SECONDS);
  30. if (success) {
  31. System.out.println("---生产者存入队列成功->data:" + data + "---");
  32. } else {
  33. System.out.println("---生产者存入队列失败->data:" + data + "---");
  34. }
  35. Thread.sleep(1000);
  36. }
  37. } catch (InterruptedException e) {
  38. e.printStackTrace();
  39. } finally {
  40. System.out.println("---生产者线程已经结束---");
  41. }
  42. }
  43.  
  44. public void stop() {
  45. this.FLAG = false;
  46. }
  47.  
  48. }
  49.  
  50. /**
  51. * 消费者线程,负责获取队列
  52. */
  53. class ConsumerThread implements Runnable {
  54.  
  55. private BlockingQueue<String> blockingQueue;
  56.  
  57. private boolean FLAG = true;
  58.  
  59. ConsumerThread(BlockingQueue<String> blockingQueue) {
  60. this.blockingQueue = blockingQueue;
  61. }
  62.  
  63. @Override
  64. public void run() {
  65. try {
  66. System.out.println("---消费者线程启动成功---");
  67. while (FLAG) {
  68. String data = blockingQueue.poll(2, TimeUnit.SECONDS);
  69. if (data == null) {
  70. System.out.println("---消费者没有获取到队列信息---");
  71. FLAG = false;
  72. return;
  73. }
  74. System.out.println("---消费者获得队列信息->data:" + data + "---");
  75. }
  76. } catch (InterruptedException e) {
  77. e.printStackTrace();
  78. } finally {
  79. System.out.println("---消费者线程已经结束---");
  80. }
  81. }
  82.  
  83. }
  84.  
  85. public class Test {
  86. public static void main(String[] args) {
  87. try {
  88. BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>(10);
  89. ProducerThread producerThread = new ProducerThread(blockingQueue);
  90. ConsumerThread consumerThread = new ConsumerThread(blockingQueue);
  91. Thread producer = new Thread(producerThread);
  92. Thread consumer = new Thread(consumerThread);
  93. producer.start();
  94. consumer.start();
  95. Thread.sleep(10000);
  96. producerThread.stop();
  97. } catch (InterruptedException e) {
  98. e.printStackTrace();
  99. }
  100. }
  101. }

打印如下:

  1. ---消费者线程启动成功---
  2. ---生产者线程启动成功---
  3. ---生产者存入队列成功->data:1---
  4. ---消费者获得队列信息->data:1---
  5. ---生产者存入队列成功->data:2---
  6. ---消费者获得队列信息->data:2---
  7. .............................................
  8. ---生产者存入队列成功->data:9---
  9. ---消费者获得队列信息->data:9---
  10. ---生产者存入队列成功->data:10---
  11. ---消费者获得队列信息->data:10---
  12. ---生产者线程已经结束---
  13. ---消费者没有获取到队列信息---
  14. ---消费者线程已经结束---

Java深入学习(2):并发队列的更多相关文章

  1. 《Effective Java》 学习笔记 —— 并发

    <Effective Java>第二版学习笔记之并发编程. 第66条 同步访问共享的可变数据 * 关键字synchronized可以保证在同一时刻只有一个线程可以执行某个方法或代码块. * ...

  2. Java多线程学习(一)---并发与多线程

    Java并发与多线程 摘要: 1. 并发与并行的区别,何为并发编程,并发编程的优势在哪 2. 多线程.多任务.多进程机制概述 3. 多线程.多任务.多进程机制与编程思想的关系 一.并发 1.1 并发与 ...

  3. Java并发包源码学习系列:基于CAS非阻塞并发队列ConcurrentLinkedQueue源码解析

    目录 非阻塞并发队列ConcurrentLinkedQueue概述 结构组成 基本不变式 head的不变式与可变式 tail的不变式与可变式 offer操作 源码解析 图解offer操作 JDK1.6 ...

  4. Java工程师学习指南第4部分:Java并发编程指南

    本文整理了微信公众号[Java技术江湖]发表和转载过的Java并发编程相关优质文章,想看到更多Java技术文章,就赶紧关注本公众号吧吧. [纯干货]Java 并发进阶常见面试题总结 [Java基本功] ...

  5. 解读 java 并发队列 BlockingQueue

    点击添加图片描述(最多60个字)编辑 今天呢!灯塔君跟大家讲: 解读 java 并发队列 BlockingQueue 最近得空,想写篇文章好好说说 java 线程池问题,我相信很多人都一知半解的,包括 ...

  6. 10分钟搞定 Java 并发队列好吗?好的

    | 好看请赞,养成习惯 你有一个思想,我有一个思想,我们交换后,一个人就有两个思想 If you can NOT explain it simply, you do NOT understand it ...

  7. Java并发队列与容器

    [前言:无论是大数据从业人员还是Java从业人员,掌握Java高并发和多线程是必备技能之一.本文主要阐述Java并发包下的阻塞队列和并发容器,其实研读过大数据相关技术如Spark.Storm等源码的, ...

  8. [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...

  9. JAVA多线程(二) 并发队列和阻塞队列

    github代码地址:https://github.com/showkawa/springBoot_2017/tree/master/spb-demo/spb-brian-query-service/ ...

随机推荐

  1. JavaWeb中的监听器

    JavaWeb中的监听器 l  事件源:三大域! ServletContext ¨       生命周期监听:ServletContextListener,它有两个方法,一个在出生时调用,一个在死亡时 ...

  2. VS Code配置Python

    安装 1.安装python插件 直接在VS Code里搜索“Python”插件,安装. 2.下载Python 去官网下载Python 其他的插件在第一次运行Python程序会提示,按要求安装即可. 运 ...

  3. ESA2GJK1DH1K基础篇: 购买云服务器

    我选择的是购买阿里云的服务器 如果是学生,可以选择 因为我用学生账户买过了,所以过程没法写了,下面我就写不用学生账户买的过程,其实应该配置过程和学生买差不多 选择购买的配置 选择系统 不需要配置直接下 ...

  4. Generator生成器函数执行过程的理解

    一个最基本的Generator函数格式如下,函数体内部要使用yield修饰符则必须在函数名前加上*号 ; function *testYield(x){ console.log('before yie ...

  5. HTML基础知识---文本编辑练习

    飘柔兰花去油洗发水液露去屑止痒控油                                         阿道夫净屑舒爽清洁头皮去屑洗发水520ml                      ...

  6. Windows远程桌面连接Debian

    参考 https://portal.databasemart.com/kb/a457/how-to-install-desktop-environment-and-xrdp-service-in-de ...

  7. vue添加背景音乐

    vue添加背景音乐需要用到HTML中的标签 参考手册:http://www.w3school.com.cn/tags/html_ref_audio_video_dom.asp *在iOS端autopl ...

  8. Sitecore 8.2 防火墙规则的权威指南

    如今,使用多层安全保护您的数据不再是奢侈品; 这是不容谈判的.此外,您需要确保Sitecore解决方案保持运行并与集成服务(例如SQL,Mongo,Solr)通信,同时保持相同的安全级别. 让我们假设 ...

  9. DRF框架和Vue框架阅读目录

    Vue框架目录 (一)Vue框架(一)——Vue导读.Vue实例(挂载点el.数据data.过滤器filters).Vue指令(文本指令v-text.事件指令v-on.属性指令v-bind.表单指令v ...

  10. JWT与RBAC权限模型

    JWT JWT是什么? Json web token (JWT)是为了网络应用环境间传递声明而执行的一种基于JSON的开发标准(RFC7519),该token被设计为紧凑且安全的,特别适用于分布式站点 ...