Java多线程_阻塞队列
1.什么是阻塞队列
我们知道,PriorityQueue、LinkedList这些都是非阻塞队列。在我们使用非阻塞队列的时候有一个很大问题,它不会对当前线程产生阻塞,那么在面对类似消费者-生产者的模型时,就必须额外地实现同步策略以及线程间唤醒策略,这个实现起来就非常麻烦。但是有了阻塞队列就不一样了,它会对当前线程产生阻塞,比如一个线程从一个空的阻塞队列中取元素,此时线程会被阻塞直到阻塞队列中有了元素。当队列中有元素后,被阻塞的线程会自动被唤醒(不需要我们编写代码去唤醒)。这样提供了极大的方便性。
2.阻塞队列的种类
阻塞队列本质上就是队列,它主要有一下几种:
- ArrayBlockingQueue:基于数组实现的阻塞队列,先进先出队列,有界队列。在创建时必须制定容量大小。并可以指定公平性与非公平性,默认情况下是非公平的,即不保证等待时间最长的队列最优先能够访问队列。
- LinkedBlockingQueue:基于链表实现的阻塞队列,先进先出队列,有界队列。在创建时如果不指定容量大小,则默认大小为Integer.MAX_VALUE。
- PriorityBlockingQueue:按照元素的优先级对元素进行排序,按照优先级顺序出队。并且该阻塞队列为无界阻塞队列,即容量没有上限(源码中它没有容器满的信号标志)。
- DelayQueue:基于PriorityQueue的延时阻塞队列,无界队列。DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列中获取到该元素。因为DelayQueue是一个无界队列,所以往队列中插入数据的操作永远不会被阻塞,而只有获取数据的操作才会被阻塞。
- SynchronousQueue:一个不存储元素的阻塞队列。
- LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
- LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。
3.阻塞队列中的几个主要方法
- put方法用来向队尾存入元素,如果队列满,则等待;
- take方法用来从队首取元素,如果队列为空,则等待;
- offer方法用来向队尾存入元素,如果队列满,则等待一定的时间,当时间期限达到时,如果还没有插入成功,则返回false;否则返回true;
- poll方法用来从队首取元素,如果队列空,则等待一定的时间,当时间期限达到时,如果取到,则返回null;否则返回取得的元素;
4.使用(以LinkedBlockingQueue为例)
import java.util.concurrent.LinkedBlockingQueue;
public class BlockingQueueDemo {
int size = 10;
LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>(size);
public static void main(String[] args) {
BlockingQueueDemo bqd = new BlockingQueueDemo();
Consumer c = bqd.new Consumer();
Productor p = bqd.new Productor();
c.setName("消费者");
p.setName("生产者");
c.start();
p.start();
}
class Consumer extends Thread {
@Override
public void run() {
consume();
}
private void consume() {
while (true) {
try {
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "消费了一个物品,还有" + queue.size() + "个物品");
}
}
}
class Productor extends Thread {
@Override
public void run() {
product();
}
private void product() {
while (true) {
try {
queue.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "生产了一个物品,现有" + queue.size() + "个物品");
}
}
}
}
Java多线程_阻塞队列的更多相关文章
- 多线程编程学习六(Java 中的阻塞队列).
介绍 阻塞队列(BlockingQueue)是指当队列满时,队列会阻塞插入元素的线程,直到队列不满:当队列空时,队列会阻塞获得元素的线程,直到队列变非空.阻塞队列就是生产者用来存放元素.消费者用来获取 ...
- java并发:阻塞队列
第一节 阻塞队列 1.1 初识阻塞队列 队列以一种先进先出的方式管理数据,阻塞队列(BlockingQueue)是一个支持两个附加操作的队列,这两个附加的操作是:在队列为空时,获取元素的线程会等待队列 ...
- Java中的阻塞队列
1. 什么是阻塞队列? 阻塞队列(BlockingQueue)是一个支持两个附加操作的队列.这两个附加的操作是:在队列为空时,获取元素的线程会等待队列变为非空.当队列满时,存储元素的线程会等待队列可用 ...
- 聊聊并发(七)——Java中的阻塞队列
3. 阻塞队列的实现原理 聊聊并发(七)--Java中的阻塞队列 作者 方腾飞 发布于 2013年12月18日 | ArchSummit全球架构师峰会(北京站)2016年12月02-03日举办,了解更 ...
- Java并发编程-阻塞队列(BlockingQueue)的实现原理
背景:总结JUC下面的阻塞队列的实现,很方便写生产者消费者模式. 常用操作方法 常用的实现类 ArrayBlockingQueue DelayQueue LinkedBlockingQueue Pri ...
- Java中的阻塞队列(BlockingQueue)
1. 什么是阻塞队列 阻塞队列(BlockingQueue)是 Java 5 并发新特性中的内容,阻塞队列的接口是 java.util.concurrent.BlockingQueue,它提供了两个附 ...
- 阻塞队列一——java中的阻塞队列
目录 阻塞队列简介:介绍阻塞队列的特性与应用场景 java中的阻塞队列:介绍java中实现的供开发者使用的阻塞队列 BlockQueue中方法:介绍阻塞队列的API接口 阻塞队列的实现原理:具体的例子 ...
- JUC之Java中的阻塞队列及其实现原理
在文章线程池实现原理 - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)中介绍了线程池的组成部分,其中一个组成部分就是阻塞队列.那么JAVA中的阻塞队列如何实现的呢? 阻塞队列,关键字是阻塞 ...
- Java中的阻塞队列-ArrayBlockingQueue(一)
最近在看一些java基础的东西,看到了队列这章,打算对复习的一些知识点做一个笔记,也算是对自己思路的一个整理,本章先聊聊java中的阻塞队列 参考文章: http://ifeve.com/java-b ...
随机推荐
- 02_Linux实操篇
第五章 VI和VIM编辑器 5.1. VI和VIM基本介绍 Vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器.由于对Unix及Linux系统的任何版本,Vi ...
- Springboot 多数据源配置,结合tk-mybatis
一.前言 作为一个资深的CRUD工程师,我们在实际使用springboot开发项目的时候,难免会遇到同时使用多个数据库的情况,比如前脚刚查询mysql,后脚就要查询sqlserver. 这时,我们很直 ...
- Debug HashMap
目录 1,HashMap面试必问 2,Debug源码的心得体会 3,JDK 1.7 3.1 用debug分析一个元素是如何加入到HashMap中的[jdk1.7] 3.2 用debug分析HashMa ...
- 9 16 模拟赛&关于线段树上二分总结
1 考试时又犯了一个致命的错误,没有去思考T2的正解而是去简单的推了一下式子开始了漫漫找规律之路,不应该这样做的 为了得到规律虽然也打了暴力 但是还是打了一些不必要的程序 例如求组合数什么的比较浪费时 ...
- react - 多层级嵌套路由支持
routerCofing配置 { path: '/route1/someModel', children: [ { path: '/route2', component: RouteBase.Cps1 ...
- 【02python基础-函数,类】
1.函数中的全局变量与局部变量全局变量:在函数和类定义之外声明的变量.作用域为定义的模块,从定义位置开始到模块结束.全局变量降低了函数的通用性和可读性,要尽量避免全局变量的使用.全局边个两一般作为常量 ...
- C++文件操作和模板
1.数据层次 位 bit 字节 byte 域/记录 将所有记录顺序地写入一个文件---->顺序文件:一个有限字符构成的顺序字符流 C++标准库中:ifsteam,ofstream,fstream ...
- Android 的重要控件 ListView (听说是最难最常用的控件)
这个打字有点慢了,左手受伤了,不过很幸运,左手小拇指没事(这就可以愉快地使用快捷键啦!),虽然有伤,但还是得坚持总结,不只是为自己,还为未来的你们铺路,希望我写的,对你们有帮助. 提前给自己一个祝福: ...
- Docker-compose实战
Docker-compose实战 各位小伙伴们,我们前面的篇文章分享了.docker的基础知识点.如何编写一个Dockerfile.docker网络是怎么回事.如何编写docker-compose.y ...
- 008_go语言中的Arrays数组
代码演示 package main import "fmt" func main() { var a [5]int fmt.Println("emp:", a) ...