并发队列:

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

ConcurrentLinkedQueue:非阻塞式队列

BlockingQueue:阻塞式队列

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

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

非阻塞无论如何都不等待

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

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

非阻塞队列:

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

打印如下:

张三
李四
王五
null

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

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

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

换一下代码:

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

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

示例:

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

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

生产者消费者示例:

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

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

package org.dreamtech;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger; /**
* 生产者线程,负责添加队列
*/
class ProducerThread implements Runnable { private BlockingQueue<String> blockingQueue; private volatile boolean FLAG = true; private AtomicInteger atomicInteger = new AtomicInteger(); ProducerThread(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
} @Override
public void run() {
try {
System.out.println("---生产者线程启动成功---");
while (FLAG) {
String data = atomicInteger.incrementAndGet() + "";
boolean success = blockingQueue.offer(data, 2, TimeUnit.SECONDS);
if (success) {
System.out.println("---生产者存入队列成功->data:" + data + "---");
} else {
System.out.println("---生产者存入队列失败->data:" + data + "---");
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("---生产者线程已经结束---");
}
} public void stop() {
this.FLAG = false;
} } /**
* 消费者线程,负责获取队列
*/
class ConsumerThread implements Runnable { private BlockingQueue<String> blockingQueue; private boolean FLAG = true; ConsumerThread(BlockingQueue<String> blockingQueue) {
this.blockingQueue = blockingQueue;
} @Override
public void run() {
try {
System.out.println("---消费者线程启动成功---");
while (FLAG) {
String data = blockingQueue.poll(2, TimeUnit.SECONDS);
if (data == null) {
System.out.println("---消费者没有获取到队列信息---");
FLAG = false;
return;
}
System.out.println("---消费者获得队列信息->data:" + data + "---");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("---消费者线程已经结束---");
}
} } public class Test {
public static void main(String[] args) {
try {
BlockingQueue<String> blockingQueue = new LinkedBlockingQueue<>(10);
ProducerThread producerThread = new ProducerThread(blockingQueue);
ConsumerThread consumerThread = new ConsumerThread(blockingQueue);
Thread producer = new Thread(producerThread);
Thread consumer = new Thread(consumerThread);
producer.start();
consumer.start();
Thread.sleep(10000);
producerThread.stop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

打印如下:

---消费者线程启动成功---
---生产者线程启动成功---
---生产者存入队列成功->data:1---
---消费者获得队列信息->data:1---
---生产者存入队列成功->data:2---
---消费者获得队列信息->data:2---
.............................................
---生产者存入队列成功->data:9---
---消费者获得队列信息->data:9---
---生产者存入队列成功->data:10---
---消费者获得队列信息->data:10---
---生产者线程已经结束---
---消费者没有获取到队列信息---
---消费者线程已经结束---

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. Selenium请求库

    阅读目录 一 介绍 二 安装 三 基本使用 四 等待元素被加载 五 选择器 六 元素交互操作 七 其他 八 项目练习 九 破解登录验证 一 介绍 1.selenium是什么? selenium最初是一 ...

  2. Ant Design Pro 鉴权/ 权限管理

    https://pro.ant.design/docs/authority-management-cn ant-design-pro 1.0.0 V4 最近需要项目需要用扫码登录,因此就使用antd ...

  3. (HK1-1)海康网络摄像机的使用

    https://blog.csdn.net/u014552102/article/details/86700057 一.手机客户端操作:  首先在莹石商城官网https://www.ys7.com/下 ...

  4. 关于时间排序在ios中失效的处理方法

    上个月公司做项目的时候在列表排序的时候产品加了一个需求,通过点击量,发布时间,评论量进行筛选的一个需求. 一开始在电脑上测试基本没问题,然后我也就放下了这个按耐不住的小心脏,然后在完成所有模块后 sh ...

  5. redis之expire命令详解

      expire是设置redis过期时间的命令,需要注意的点有以下几点 expire设置过期时间的单位是秒,如设置name的过期时间为1000秒 expire name 1000 超过时间后会自动删除 ...

  6. 洛谷 P2023 [AHOI2009]维护序列 题解

    P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,-,aN .有如下三种操作形式: (1)把数列中 ...

  7. 函数$f(x+1)$和$f(x-1)$的奇偶性

    前言 廓清认知 1.函数\(y=f(x)\)的奇偶性 ①\(y=f(x)\)为奇函数,则满足\(f(-x)+f(x)=0\),即关于点\((0,0)\)对称: ②\(y=f(x)\)为偶函数,则满足\ ...

  8. 团体项目(饱了嘛)_第一组_UML图

    UML图 需求分析报告 https://www.cnblogs.com/Clover-yee/p/11771395.html 类图 user(用户类):主要保存用户的基本信息 shop(商铺类):主要 ...

  9. No module named 'requests_toolbelt'

    pip install requests-toolbelt

  10. servlet生成json数据返回至Ajax

    一.JSON JSON是一种取代XML的数据结构,和xml相比,它更小巧但描述能力却不差,由于它的小巧所以网络传输数据将减少更多流量从而加快速度. JSON就是一串字符串 只不过元素会使用特定的符号标 ...