JUC 并发编程--06, 阻塞队列(7种), 阻塞等待 api的 代码验证


这些队列的 api ,就是添加队列,出队列,检测对首元素, 由于 add()--remove(), offer()--poll(),太简单这里不做验证, 只验证后二组api: 阻塞等待( put()--take() ), 超时等待( offer()--poll() )
多线程下,验证:
public static void main(String[] args) throws InterruptedException {
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue(3);
/**
* 阻塞 等待 的 api: 添加队列put(), 出队列take()
*
* take(),从队列中取元素, 如果队列中没有元素,就在这里阻塞,直到队列中有元素,他取走为止, 不拿到元素死不罢休
* put(), 放元素到队列中, 如果队列已经满了,就在这里阻塞,直到队列的元素被取走,取走一个放入一个, 一定要放元素到队列中,哪怕等到天荒地老
*/
//验证 take(), 不拿到元素死不罢休
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName() + "这里获取不到任何东西,所以在这里阻塞等待....");
String take = arrayBlockingQueue.take();
System.out.println(Thread.currentThread().getName() + "获取到的值为:" + take);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程1").start();
// 这里睡1秒,目的是让 线程1 先执行
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName() + "抢到执行权, 此线程放数据开始");
arrayBlockingQueue.put("1");
arrayBlockingQueue.put("2");
arrayBlockingQueue.put("3");
System.out.println(Thread.currentThread().getName() + "放入成功");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程2").start();
while(Thread.activeCount()>2){}
System.out.println("打印2:"+arrayBlockingQueue);
}
运行结果:

ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue(3);
/**
* 阻塞 等待 的 api: 添加队列put(), 出队列take()
*
* take(),从队列中取元素, 如果队列中没有元素,就在这里阻塞,直到队列中有元素,他取走为止, 不拿到元素死不罢休
* put(), 放元素到队列中, 如果队列已经满了,就在这里阻塞,直到队列的元素被取走,取走一个放入一个, 一定要放元素到队列中,哪怕等到天荒地老
*/
//验证 put(), 一定要放元素到队列,哪怕等到天荒地老
arrayBlockingQueue.put("123");
arrayBlockingQueue.put("456");
arrayBlockingQueue.put("789");
System.out.println("打印1:"+arrayBlockingQueue);
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName() + "想放元素000 到队列中,但此时队列满了,所以开始等待");
arrayBlockingQueue.put("000");
System.out.println(Thread.currentThread().getName() + "等待结束了, 终于将000放入队列中了, 结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程1").start();
// 这里睡1秒,目的是让 线程1 先执行
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName() + "抢到执行权. 开始移除一个元素");
String take = arrayBlockingQueue.take();
System.out.println(Thread.currentThread().getName() + "将 "+take+" 移除队列, 方便 线程1 放元素");
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程2").start();
while(Thread.activeCount()>2){}
System.out.println("打印2:"+arrayBlockingQueue);
运行结果:

超时等待 的 api 代码验证
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue(3);
/**
* 超时等待:带等待时间参数的: 添加队列 offer(,,) 移除队列 poll(,,)
*
* offer(,,) : 队列满了, 就在这里等待, 如果一定时间内.还没有元素被取出, 超过这个世界就退出等待
* poll(,,) : 队列为空, 就在这里等待, 如果一定时间内,还没有元素添加到队列中, 超过这个时间就退出等待
*/
//验证offer(,,)
arrayBlockingQueue.put("123");
arrayBlockingQueue.put("456");
arrayBlockingQueue.put("789");
System.out.println("初始队列:"+arrayBlockingQueue);
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName() + "想要往队列中放元素 0000, 但此时队列已满,等待3秒,3秒之内如果没有元素移除 , 就退出等待,不添加");
arrayBlockingQueue.offer("0000",3,TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程1").start();
new Thread(()->{
try {
//TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName() + "抢到执行权,开始移除一个元素");
arrayBlockingQueue.poll();
} catch (Exception e) {
e.printStackTrace();
}
},"线程2").start();
while(Thread.activeCount()>2){}
System.out.println("打印2:"+arrayBlockingQueue);
}
运行结果为: 可以看到,队列满, 线程1等了3秒, 3秒内刚好线程2 移除了一个元素, 所以线程1,退出等待,添加0000到队列中

如果: 线程2 睡5秒呢? 此时可以看到, 线程1 等了3秒,队列依旧是满的, 就退出等待,不执行添加操作, 运行结果为:

验证 超时等待 poll(,,)
ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue(3);
/**
* 超时等待:带等待时间参数的: 添加队列 offer(,,) 移除队列 poll(,,)
*
* offer(,,) : 队列满了, 就在这里等待, 如果一定时间内.还没有元素被取出, 超过这个世界就退出等待
* poll(,,) : 队列为空, 就在这里等待, 如果一定时间内,还没有元素添加到队列中, 超过这个时间就退出等待
*/
//验证 poll(,,)
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName() + "此时队列为空, 等待3秒,如果3秒内,队列仍然为空,就退出等待,不为空就执行出队列操作");
String poll = arrayBlockingQueue.poll(3, TimeUnit.SECONDS);
System.out.println(Thread.currentThread().getName() + "取出的元素是:" + poll);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程1").start();
new Thread(()->{
try {
//TimeUnit.SECONDS.sleep(5);
System.out.println(Thread.currentThread().getName() + "开始往队列中放元素");
arrayBlockingQueue.offer("123");
arrayBlockingQueue.offer("456");
System.out.println(Thread.currentThread().getName() + "入队结束");
} catch (Exception e) {
e.printStackTrace();
}
},"线程2").start();
while(Thread.activeCount()>2){}
System.out.println("打印2:"+arrayBlockingQueue);
运行结果: 队列空,线程1,等待3秒, 刚好3秒内,线程2,往队列中添加了元素, 所以 线程1 取到了元素

如果线程2 等待5秒: 线程1将取不到元素 为null, 结果为:

JUC 并发编程--06, 阻塞队列(7种), 阻塞等待 api的 代码验证的更多相关文章
- JUC 并发编程--12, 使用AtomicInteger 实现一把锁(排队自旋锁), 代码演示
前面 使用自旋锁实现了一把锁,(请看 第5篇) volatile 三大特性: 可见性, 不保证原子性, 禁止指令重排 为了解决 volatile不保证原子性的问题, 引入了原子类, AtomicInt ...
- 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理
· 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...
- Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程
Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...
- 并发编程 06—— CompletionService :Executor 和 BlockingQueue
Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭 ...
- JUC并发编程学习笔记
JUC并发编程学习笔记 狂神JUC并发编程 总的来说还可以,学到一些新知识,但很多是学过的了,深入的部分不多. 线程与进程 进程:一个程序,程序的集合,比如一个音乐播发器,QQ程序等.一个进程往往包含 ...
- Python 3 并发编程多进程之队列(推荐使用)
Python 3 并发编程多进程之队列(推荐使用) 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 可以往 ...
- 自己总结 :并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结
并发队列ConcurrentLinkedQueue.阻塞队列AraayBlockingQueue.阻塞队列LinkedBlockingQueue 区别 和 使用场景总结 分类: Java2013-0 ...
- JUC并发编程基石AQS之主流程源码解析
前言 由于AQS的源码太过凝练,而且有很多分支比如取消排队.等待条件等,如果把所有的分支在一篇文章的写完可能会看懵,所以这篇文章主要是从正常流程先走一遍,重点不在取消排队等分支,之后会专门写一篇取消排 ...
- JUC 并发编程--07 阻塞队列版本的 生产者消费者(不使用synchronized和 lock),也有一些疑惑,最终解惑
直接上代码: 前提是你已经 熟悉了原子类,volatile,和阻塞队列 public class JucPCdemo03 { /** * 阻塞队列的应用: 这里实现的生产者消费者,生产一个消费一个 * ...
随机推荐
- Linux下的用户、组和权限
目录 一:用户和组信息的查看 查看用户信息 查看密码信息 查看组信息 特殊组wheel 二:用户和组信息的管理 用户管理 组管理 三:文件权限 文件权限的查看 文件权限的修改 ACL控制权限 setf ...
- POJ1094查分约束,判断关系是否唯一
题意: 给你一些a<b的关系,然后有三组询问. 1 当前这组之后如果能确定这n个数的大小关系,那么就输出关系 2 当前时候出现bug,就是和前面如果冲突,那么就不行 3 最后的答案是 ...
- Python 爬虫 BeautifulSoup4 库的使用
BeautifulSoup4库 和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据.lxml 只会局部遍历,而Be ...
- 【JavaScript】Leetcode每日一题-移除元素
[JavaScript]Leetcode每日一题-移除元素 [题目描述] 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度. 不要使用 ...
- 【python】Leetcode每日一题-删除排序链表中的重复元素2
[python]Leetcode每日一题-删除排序链表中的重复元素2 [题目描述] 存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表 ...
- 【opencv】Java实现opencv 调用本地摄像头,实现人脸识别、人形识别、人眼识别
本博客为老魏原创,如需转载请留言咨询. 效果预览:(没办法,为了效果只能上像了,丑别介意.哈哈..) 上代码: 1 package com.lw.test; 2 3 import java.awt.G ...
- 『政善治』Postman工具 — 9、在Postman中使用断言
目录 1.Tests的介绍 2.常用SNIPPETS(片段)说明 (1)常用变量相关 (2)状态码相关 (3)响应结果断言: (4)Header : (5)响应速度: 3.示例 (1)响应码断言 (2 ...
- MySQL密码复杂度与密码过期策略介绍
前言: 年底了,你的数据库是不是该巡检了?一般巡检都会关心密码安全问题,比如密码复杂度设置,是否有定期修改等.特别是进行等保评测时,评测机构会要求具备密码安全策略.其实 MySQL 系统本身可以设置密 ...
- 从系统的角度分析影响程序执行性能的因素——SA20225205 黄兴宇
实验总结分析报告:从系统的角度分析影响程序执行性能的因素 1.请您根据本课程所学内容总结梳理出一个精简的Linux系统概念模型,最大程度统摄整顿本课程及相关的知识信息,模型应该是逻辑上可以运转的.自洽 ...
- 实施CRM系统后 企业客户服务的改变
通过实施CRM客户管理系统,企业的竞争力和盈利能力得到大幅提高.在这个过程中,客户服务不仅能够持续的满足客户的需求,还能够促进客户与企业建立长期的互惠互利的良好客户关系,这也为企业赢得了更多的商机和利 ...