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

  1. public class BlockingQueueTest {
  2. private static ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(5, true); //最大容量为5的数组堵塞队列
  3. //private static LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(5);
  4. private static CountDownLatch producerLatch; //倒计时计数器
  5. private static CountDownLatch consumerLatch;
  6. public static void main(String[] args) {
  7. BlockingQueueTest queueTest = new BlockingQueueTest();
  8. queueTest.test();
  9. }
  10. private void test(){
  11. producerLatch = new CountDownLatch(10); //state值为10
  12. consumerLatch = new CountDownLatch(10); //state值为10
  13. Thread t1 = new Thread(new ProducerTask());
  14. Thread t2 = new Thread(new ConsumerTask());
  15. //启动线程
  16. t1.start();
  17. t2.start();
  18. try {
  19. System.out.println("producer waiting...");
  20. producerLatch.await(); //进入等待状态,直到state值为0,再继续往下执行
  21. System.out.println("producer end");
  22. } catch (InterruptedException e) {
  23. e.printStackTrace();
  24. }
  25. try {
  26. System.out.println("consumer waiting...");
  27. consumerLatch.await(); //进入等待状态,直到state值为0,再继续往下执行
  28. System.out.println("consumer end");
  29. } catch (InterruptedException e) {
  30. e.printStackTrace();
  31. }
  32. //结束线程
  33. t1.interrupt();
  34. t2.interrupt();
  35. System.out.println("end");
  36. }
  37. //生产者
  38. class ProducerTask implements Runnable{
  39. private Random rnd = new Random();
  40. @Override
  41. public void run() {
  42. try {
  43. while(true){
  44. queue.put(rnd.nextInt(100)); //如果queue容量已满,则当前线程会堵塞,直到有空间再继续
  45. //offer方法为非堵塞的
  46. //queue.offer(rnd.nextInt(100), 1, TimeUnit.SECONDS); //等待1秒后还不能加入队列则返回失败,放弃加入
  47. //queue.offer(rnd.nextInt(100));
  48. producerLatch.countDown(); //state值减1
  49. //TimeUnit.SECONDS.sleep(2); //线程休眠2秒
  50. }
  51. } catch (InterruptedException e) {
  52. //e.printStackTrace();
  53. }  catch (Exception ex){
  54. ex.printStackTrace();
  55. }
  56. }
  57. }
  58. //消费者
  59. class ConsumerTask implements Runnable{
  60. @Override
  61. public void run() {
  62. try {
  63. while(true){
  64. Integer value = queue.take(); //如果queue为空,则当前线程会堵塞,直到有新数据加入
  65. //poll方法为非堵塞的
  66. //Integer value = queue.poll(1, TimeUnit.SECONDS); //等待1秒后还没有数据可取则返回失败,放弃获取
  67. //Integer value = queue.poll();
  68. System.out.println("value = " + value);
  69. consumerLatch.countDown(); //state值减1
  70. TimeUnit.SECONDS.sleep(2); //线程休眠2秒
  71. }
  72. } catch (InterruptedException e) {
  73. //e.printStackTrace();
  74. } catch (Exception ex){
  75. ex.printStackTrace();
  76. }
  77. }
  78. }
  79. }

ArrayBlockingQueue和LinkedBlockingQueue的使用的更多相关文章

  1. ArrayBlockingQueue跟LinkedBlockingQueue的区别

    .队列中的锁的实现不同 ArrayBlockingQueue中的锁是没有分离的,即生产和消费用的是同一个锁: LinkedBlockingQueue中的锁是分离的,即生产用的是putLock,消费是t ...

  2. ArrayBlockingQueue和LinkedBlockingQueue分析

        JAVA并发包提供三个常用的并发队列实现,分别是:ConcurrentLinkedQueue.LinkedBlockingQueue和ArrayBlockingQueue. Concurren ...

  3. JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue

    JDK源码分析—— ArrayBlockingQueue 和 LinkedBlockingQueue 目的:本文通过分析JDK源码来对比ArrayBlockingQueue 和LinkedBlocki ...

  4. ArrayBlockingQueue和LinkedBlockingQueue的区别

    ArrayBlockingQueue和LinkedBlockingQueue的区别,得出结论如下: 1. 队列中锁的实现不同 ArrayBlockingQueue实现的队列中的锁是没有分离的,即生产和 ...

  5. Java 容器源码分析之ArrayBlockingQueue和LinkedBlockingQueue

    Java中的阻塞队列接口BlockingQueue继承自Queue接口. BlockingQueue接口提供了3个添加元素方法. add:添加元素到队列里,添加成功返回true,由于容量满了添加失败会 ...

  6. ArrayBlockingQueue和LinkedBlockingQueue

    1.BlockingQueue接口定义了一种阻塞的FIFO queue ArrayBlockingQueue和LinkedBlockingQueue的区别: 1. 队列中锁的实现不同 ArrayBlo ...

  7. ArrayBlockingQueue,LinkedBlockingQueue分析

    BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会 ...

  8. 20.并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解

    1. ArrayBlockingQueue简介 在多线程编程过程中,为了业务解耦和架构设计,经常会使用并发容器用于存储多线程间的共享数据,这样不仅可以保证线程安全,还可以简化各个线程操作.例如在“生产 ...

  9. java并发编程(二十四)----(JUC集合)ArrayBlockingQueue和LinkedBlockingQueue介绍

    这一节我们来了解阻塞队列(BlockingQueue),BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,当容量满时往BlockingQ ...

随机推荐

  1. 面向对象第三单元博客(JML)

    // demo/Graph.java package demo; ​ import java.util.ArrayList; ​ public class Demo { /*@ public norm ...

  2. Linux服务器(Centos)上安装jexus

    哈子是Jexus Jexus是一款Linux平台上的高性能WEB服务器和负载均衡网关,Jexus Web Service,简称JWS,以支持ASP.NET.ASP.NET CORE.PHP为特色, 同 ...

  3. 北京大学公开课《数据结构与算法Python版》

    之前我分享过一个数据结构与算法的课程,很多小伙伴私信我问有没有Python版. 看了一些公开课后,今天特向大家推荐北京大学的这门课程:<数据结构与算法Python版>. 课程概述 很多同学 ...

  4. CF230B T-primes 题解

    原题链接 简要题意: 判断一个数是否只有 \(3\) 个因数. 首先,如果一个数有奇数个因数,那么这个数是完全平方数. 道理很简单:因数是成对的,那么必然存在 \(k^2 = n\),此时 \(k\) ...

  5. [Redis] 万字长文带你总结Redis,助你面试升级打怪

    文章目录 Redis的介绍.优缺点.使用场景 Linux中的安装 常用命令 Redis各个数据类型及其使用场景 Redis字符串(String) Redis哈希(Hash) Redis列表(List) ...

  6. Linux系统c语言开发环境

    项目 内容 这个作业属于哪个课程 班级地址 这个作业要求在哪里 作业要求地址 学号-姓名 17041506-张政 学习目标 Linux系统下C语言开发环境搭建,学习Linux系统环境C语言开发过程 L ...

  7. 爬虫&Selenium&ChromeDriver

    一.Selenium selenium是什么 Selenium [1] 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, ...

  8. Pandas和Numpy的一些金融相关的操作(一)

    Pandas和Numpy的一些金融相关的操作 给定一个净值序列,求出最大回撤 # arr是一个净值的np.ndarray i = np.argmax( (np.maximum.acumulate(ar ...

  9. 【NLP面试QA】激活函数与损失函数

    目录 Sigmoid 函数的优缺点是什么 ReLU的优缺点 什么是交叉熵 为什么分类问题的损失函数为交叉熵而不能是 MSE? 多分类问题中,使用 sigmoid 和 softmax 作为最后一层激活函 ...

  10. coding++:thymelef 模板报错 the entity name must immediately follow the '&' in the entity reference

    thymelef模板里面是不能实用&符号的 要用&转义符代替,官网也有文档说明可以用官方的通配符代替, 官方文档 http://www.thymeleaf.org/doc/tutori ...