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. ajax上传文件,通过FromData把数据传给后端

    前端代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  2. [C++]请麻烦压一下定理的棺材板啦

    从去年还在竞赛的时候2/12的原博客里搬运来的 不得不说之前取名真的很艺术qwq 今天开始上的数论课,让头发以肉眼可见的速度掉落emmm 没关系我头发多我不怕啦啦啦QwQ 其中最令人头疼的就是那些人名 ...

  3. window 查看端口 杀端口

    最近写项目,总是出现端口被占用的问题,原来傻傻的把电脑重启一下,终于有一天受不了了,想要想办法解决.刚开始从网上找了好多教程,发现不行.开始自己尝试,终于,成功的将占用端口的进程杀掉.在此记录下过程( ...

  4. 全文搜索技术--solr7.1之mysql的安装步骤

    1.安装命令 #>在线安装wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm 输完上面一句话不能正常的下载安装 ...

  5. css3笔记系列-3.css中的各种选择器详解,不看后悔系列

    点击上方蓝色字体,关注我 最详细的css3选择器解析 ​ 选择器是什么? 比较官方的解释:在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素. 最常见的 CSS 选择器是元素选择器.换句话说 ...

  6. django复习 以及源码

    django请求生命周期 在浏览器上输入网址会发生什么事?(地址会朝我对应的ip地址发送get请求,get请求遵循http协议)先进入实现了wsgi协议的web服务器---->进入django- ...

  7. Leetcode_474. 一和零(二维01背包)

    每个字符串看成一个物品,两个属性是0和1的个数,转换为01背包. code class Solution { public: int w[605][2]; int dp[105][105]; int ...

  8. 干货|漫画算法:LRU从实现到应用层层剖析(第一讲)

    今天为大家分享很出名的LRU算法,第一讲共包括4节. LRU概述 LRU使用 LRU实现 Redis近LRU概述 第一部分:LRU概述 LRU是Least Recently Used的缩写,译为最近最 ...

  9. effective-java学习笔记---使用枚举类型替代整型常量34

    1.要将数据与枚举常量相关联,请声明实例属性并编写一个构造方法,构造方法带有数据并将数据保存在属性中. // Enum type with data and behavior public enum ...

  10. TensorFlow 神经机器教程-TensorFlow Neural Machine Translation Tutorial

    seq2seq 模型在广泛的任务比如机器翻译,语音识别,文本总结中取得了巨大的成功.这个教程给读者 seq2seq 模型一个完整的理解,并且展示如何从原型建立一个有竞争力的 seq2seq 模型.我们 ...