ArrayBlockingQueue和LinkedBlockingQueue的使用
BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会阻塞。
ArrayBlockingQueue是一个由数组支持的有界阻塞队列。在读写操作上都需要锁住整个容器,因此吞吐量与一般的实现是相似的,适合于实现“生产者消费者”模式。
基于链表的阻塞队列,同ArrayListBlockingQueue类似,其内部也维持着一个数据缓冲队列(该队列由一个链表构成),当生产者往队列中放入一个数据时,队列会从生产者手中获取数据,并缓存在队列内部,而生产者立即返回;只有当队列缓冲区达到最大值缓存容量时(LinkedBlockingQueue可以通过构造函数指定该值),才会阻塞生产者队列,直到消费者从队列中消费掉一份数据,生产者线程会被唤醒,反之对于消费者这端的处理也基于同样的原理。而LinkedBlockingQueue之所以能够高效的处理并发数据,还因为其对于生产者端和消费者端分别采用了独立的锁来控制数据同步,这也意味着在高并发的情况下生产者和消费者可以并行地操作队列中的数据,以此来提高整个队列的并发性能。
ArrayBlockingQueue和LinkedBlockingQueue的区别:
1. 队列中锁的实现不同
ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和消费用的是同一个锁;
LinkedBlockingQueue实现的队列中的锁是分离的,即生产用的是putLock,消费是takeLock
2. 在生产或消费时操作不同
ArrayBlockingQueue实现的队列中在生产和消费的时候,是直接将枚举对象插入或移除的;
LinkedBlockingQueue实现的队列中在生产和消费的时候,需要把枚举对象转换为Node<E>进行插入或移除,会影响性能
3. 队列大小初始化方式不同
ArrayBlockingQueue实现的队列中必须指定队列的大小;
LinkedBlockingQueue实现的队列中可以不指定队列的大小,但是默认是Integer.MAX_VALUE
- public class BlockingQueueTest {
- private static ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(5, true); //最大容量为5的数组堵塞队列
- //private static LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(5);
- private static CountDownLatch producerLatch; //倒计时计数器
- private static CountDownLatch consumerLatch;
- public static void main(String[] args) {
- BlockingQueueTest queueTest = new BlockingQueueTest();
- queueTest.test();
- }
- private void test(){
- producerLatch = new CountDownLatch(10); //state值为10
- consumerLatch = new CountDownLatch(10); //state值为10
- Thread t1 = new Thread(new ProducerTask());
- Thread t2 = new Thread(new ConsumerTask());
- //启动线程
- t1.start();
- t2.start();
- try {
- System.out.println("producer waiting...");
- producerLatch.await(); //进入等待状态,直到state值为0,再继续往下执行
- System.out.println("producer end");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- try {
- System.out.println("consumer waiting...");
- consumerLatch.await(); //进入等待状态,直到state值为0,再继续往下执行
- System.out.println("consumer end");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- //结束线程
- t1.interrupt();
- t2.interrupt();
- System.out.println("end");
- }
- //生产者
- class ProducerTask implements Runnable{
- private Random rnd = new Random();
- @Override
- public void run() {
- try {
- while(true){
- queue.put(rnd.nextInt(100)); //如果queue容量已满,则当前线程会堵塞,直到有空间再继续
- //offer方法为非堵塞的
- //queue.offer(rnd.nextInt(100), 1, TimeUnit.SECONDS); //等待1秒后还不能加入队列则返回失败,放弃加入
- //queue.offer(rnd.nextInt(100));
- producerLatch.countDown(); //state值减1
- //TimeUnit.SECONDS.sleep(2); //线程休眠2秒
- }
- } catch (InterruptedException e) {
- //e.printStackTrace();
- } catch (Exception ex){
- ex.printStackTrace();
- }
- }
- }
- //消费者
- class ConsumerTask implements Runnable{
- @Override
- public void run() {
- try {
- while(true){
- Integer value = queue.take(); //如果queue为空,则当前线程会堵塞,直到有新数据加入
- //poll方法为非堵塞的
- //Integer value = queue.poll(1, TimeUnit.SECONDS); //等待1秒后还没有数据可取则返回失败,放弃获取
- //Integer value = queue.poll();
- System.out.println("value = " + value);
- consumerLatch.countDown(); //state值减1
- TimeUnit.SECONDS.sleep(2); //线程休眠2秒
- }
- } catch (InterruptedException e) {
- //e.printStackTrace();
- } catch (Exception ex){
- ex.printStackTrace();
- }
- }
- }
- }
ArrayBlockingQueue和LinkedBlockingQueue的使用的更多相关文章
- ArrayBlockingQueue跟LinkedBlockingQueue的区别
.队列中的锁的实现不同 ArrayBlockingQueue中的锁是没有分离的,即生产和消费用的是同一个锁: LinkedBlockingQueue中的锁是分离的,即生产用的是putLock,消费是t ...
- ArrayBlockingQueue和LinkedBlockingQueue分析
JAVA并发包提供三个常用的并发队列实现,分别是:ConcurrentLinkedQueue.LinkedBlockingQueue和ArrayBlockingQueue. Concurren ...
- JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue
JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue 目的:本文通过分析JDK源码来对比ArrayBlockingQueue 和LinkedBlocki ...
- ArrayBlockingQueue和LinkedBlockingQueue的区别
ArrayBlockingQueue和LinkedBlockingQueue的区别,得出结论如下: 1. 队列中锁的实现不同 ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和 ...
- Java 容器源码分析之ArrayBlockingQueue和LinkedBlockingQueue
Java中的阻塞队列接口BlockingQueue继承自Queue接口. BlockingQueue接口提供了3个添加元素方法. add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会 ...
- ArrayBlockingQueue和LinkedBlockingQueue
1.BlockingQueue接口定义了一种阻塞的FIFO queue ArrayBlockingQueue和LinkedBlockingQueue的区别: 1. 队列中锁的实现不同 ArrayBlo ...
- ArrayBlockingQueue,LinkedBlockingQueue分析
BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会 ...
- 20.并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解
1. ArrayBlockingQueue简介 在多线程编程过程中,为了业务解耦和架构设计,经常会使用并发容器用于存储多线程间的共享数据,这样不仅可以保证线程安全,还可以简化各个线程操作.例如在“生产 ...
- java并发编程(二十四)----(JUC集合)ArrayBlockingQueue和LinkedBlockingQueue介绍
这一节我们来了解阻塞队列(BlockingQueue),BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,当容量满时往BlockingQ ...
随机推荐
- 《Python学习手册 第五版》 -第15章 文档
本章主要介绍Python中的文档,会通过多种方式来说明,如果查看Python自带文档和其他参考的资料 本章重点内容 1.#注释:源文件文档 2.dir函数:以列表显示对象中可用的属性 3.文档字符串 ...
- 读书笔记——莫提默·J.艾德勒&查尔斯·范多伦(美)《如何阅读一本书》
第一篇 阅读的层次 第一章 阅读的活力与艺术 阅读的目标:娱乐.获得资讯.增进理解力这本书是为那些想把读书的主要目的当作是增进理解能力的人而写.何谓阅读艺术?这是一个凭借着头脑运作,除了玩味读物中的一 ...
- springboot基础-redis集群
一.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="h ...
- 五分钟学Java:一篇文章带你搞懂spring全家桶套餐
原创声明 本文首发于微信公众号[程序员黄小斜] 本文作者:黄小斜 转载请务必在文章开头注明出处和作者. 本文思维导图 什么是Spring,为什么你要学习spring? 你第一次接触spring框架是在 ...
- Python第四章-流程控制
流程控制 在以前的代码中,所有的代码都是交由 Python 忠实地从头执行到结束.但是这些远远不够.很多时候需要根据不同的情况执行不同的代码. 如果你想改变这一工作流程,应该怎么做? 就像这样的情况: ...
- OpenCV-Python 特征匹配 + 单应性查找对象 | 四十五
目标 在本章节中,我们将把calib3d模块中的特征匹配和findHomography混合在一起,以在复杂图像中找到已知对象. 基础 那么我们在上一环节上做了什么?我们使用了queryImage,找到 ...
- 图的广度优先遍历(bfs)
广度优先遍历: 1.将起点s 放入队列Q(访问) 2.只要Q不为空,就循环执行下列处理 (1)从Q取出顶点u 进行访问(访问结束) (2)将与u 相邻的未访问顶点v 放入Q, 同时将d[v]更新为d[ ...
- [vios1023]维多利亚的舞会3<强联通分量tarjan>
题目链接:https://vijos.org/p/1023 最近在练强联通分量,当然学的是tarjan算法 而这一道题虽然打着难度为3,且是tarjan算法的裸题出没在vijos里面 但其实并不是纯粹 ...
- 【python系统学习12】函数
函数 函数是一堆组织好的.可重复利用的.用来实现某一功能的代码. python中的input().print().type().bool().len()等都是函数.且是python的内置函数. 我们也 ...
- Javascript/Jquery实现日期前一天后一天
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...