文章目录

  • 概述
  • 类图结构
  • 主要方法
    • offer操作


概述

Java Review - 并发编程_ConcurrentLinkedQueue原理&源码剖析
介绍了使用CAS算法实现的非阻塞队列ConcurrentLinkedQueue,下面我们来介绍使用独占锁实现的阻塞队列LinkedBlockingQueue


类图结构

首先看一下LinkedBlockingQueue的类图结构,以便从全局对LinkedBlockingQueue有个直观的了解

  • 由类图可以看到,LinkedBlockingQueue也是使用单向链表实现的,其也有两个Node,分别用来存放首、尾节点,并且还有一个初始值为0的原子变量count,用来记录队列元素个数。

  • 另外还有两个ReentrantLock的实例,分别用来控制元素入队和出队的原子性,其中takeLock用来控制同时只有一个线程可以从队列头获取元素,其他线程必须等待,putLock控制同时只能有一个线程可以获取锁,在队列尾部添加元素,其他线程必须等待

  • 另外,notEmpty和notFull是条件变量,它们内部都有一个条件队列用来存放进队和出队时被阻塞的线程,其实这是生产者—消费者模型

/** Current number of elements */private final AtomicInteger count = new AtomicInteger();/*** Head of linked list.* Invariant: head.item == null*/transient Node<E> head;/*** Tail of linked list.* Invariant: last.next == null*/private transient Node<E> last;/** Lock held by take, poll, etc */private final ReentrantLock takeLock = new ReentrantLock();/** Wait queue for waiting takes */private final Condition notEmpty = takeLock.newCondition();/** Lock held by put, offer, etc */private final ReentrantLock putLock = new ReentrantLock();/** Wait queue for waiting puts */private final Condition notFull = putLock.newCondition();
  • 当调用线程在LinkedBlockingQueue实例上执行take、 poll等操作时需要获取到takeLock锁,从而保证同时只有一个线程可以操作链表头节点。另外由于条件变量notEmpty内部的条件队列的维护使用的是takeLock的锁状态管理机制,所以在调用notEmpty的await和signal方法前调用线程必须先获取到takeLock锁,否则会抛出IllegalMonitorStateException异常。notEmpty内部则维护着一个条件队列,当线程获取到takeLock锁后调用notEmpty的await方法时,调用线程会被阻塞,然后该线程会被放到notEmpty内部的条件队列进行等待,直到有线程调用了notEmpty的signal方法。

  • 在LinkedBlockingQueue实例上执行put、offer等操作时需要获取到putLock锁,从而保证同时只有一个线程可以操作链表尾节点。同样由于条件变量notFull内部的条件队列的维护使用的是putLock的锁状态管理机制,所以在调用notFull的await和signal方法前调用线程必须先获取到putLock锁,否则会抛出IllegalMonitorStateException异常。notFull内部则维护着一个条件队列,当线程获取到putLock锁后调用notFull的await方法时,调用线程会被阻塞,然后该线程会被放到notFull内部的条件队列进行等待,直到有线程调用了notFull的signal方法。

如下是LinkedBlockingQueue的无参构造函数的代码。

/*** A constant holding the maximum value an {@code int} can* have, 2<sup>31</sup>-1.*/@Native public static final int   MAX_VALUE = 0x7fffffff;/*** Creates a {@code LinkedBlockingQueue} with a capacity of* {@link Integer#MAX_VALUE}.*/public LinkedBlockingQueue() {this(Integer.MAX_VALUE);}public LinkedBlockingQueue(int capacity) {if (capacity <= 0) throw new IllegalArgumentException();this.capacity = capacity;// 初始化首 尾节点,并让它指向哨兵节点last = head = new Node<E>(null);}

由该代码可知,默认队列容量为0x7fffffff,用户也可以自己指定容量,所以从一定程度上可以说LinkedBlockingQueue是有界阻塞队列。


主要方法

offer操作

Java Review - 并发编程_LinkedBlockingQueue原理源码剖析相关推荐

  1. Java Review - 并发编程_ArrayBlockingQueue原理源码剖析

    文章目录 概述 类图结构 构造函数 主要方法源码解析 offer操作 put操作 poll操作 take操作 peek操作 size 小结 概述 Java Review - 并发编程_LinkedBl ...

  2. Java Review - 并发编程_ScheduledThreadPoolExecutor原理源码剖析

    文章目录 概述 类结构 核心方法&源码解析 schedule(Runnable command, long delay,TimeUnit unit) scheduleWithFixedDela ...

  3. Java Review - 并发编程_DelayQueue原理源码剖析

    文章目录 概述 类图结构 小Demo 核心方法&源码解读 offer操作 take操作 poll操作 size操作 小结 概述 DelayQueue并发队列是一个无界阻塞延迟队列,队列中的每个 ...

  4. Java Review - 并发编程_ThreadPoolExecutor原理源码剖析

    文章目录 线程池主要解决两个问题 类关系图 ctl 含义 ---- 记录线程池状态和线程池中线程个数 线程池状态 及转换 线程池参数 线程池类型 mainLock & termination ...

  5. Java Review - 并发编程_ConcurrentLinkedQueue原理源码剖析

    文章目录 概述 ConcurrentLinkedQueue 核心方法&源码解读 offer add poll peek size remove contains 总结 概述 JDK中提供了一系 ...

  6. Java Review - 并发编程_PriorityBlockingQueue原理源码剖析

    文章目录 概述 类图结构 小Demo 核心方法&源码解析 offer poll put take size 概述 PriorityBlockingQueue是带优先级的无界阻塞队列,每次出队都 ...

  7. Java Review - 并发编程_原子操作类原理剖析

    文章目录 概述 原子变量操作类 主要方法 incrementAndGet .decrementAndGet .getAndIncrement.getAndDecrement boolean compa ...

  8. Java Review - 并发编程_原子操作类LongAdder LongAccumulator剖析

    文章目录 概述 小Demo 源码分析 重要的方法 long sum() reset sumThenReset longValue() add(long x) longAccumulate(long x ...

  9. Java Review - 并发编程_ 回环屏障CyclicBarrier原理源码剖析

    文章目录 Pre 小Demo 类图结构 CyclicBarrier核心方法源码解读 int await() int await(long timeout, TimeUnit unit) int dow ...

最新文章

  1. .NET平台BigO算法复杂度备忘
  2. BZOJ2437 [Noi2011]兔兔与蛋蛋 【博弈论 + 二分图匹配】
  3. python学习三:列表,元组
  4. SQL Server事务
  5. android studio scala插件,Scala 语言开发Andorid ,开发环境的搭建(一)
  6. android 监听手机电量变化
  7. pytorch实现L2和L1正则化regularization的方法
  8. 基于.NET CORE微服务框架 -谈谈surging API网关
  9. mybatis3中@SelectProvider的使用技巧
  10. Storm任务提交过程及目录树介绍
  11. mysql视图使用方法
  12. java sublist_java中的subList
  13. PPPoE原理和实验
  14. Quartz 触发器、过期触发策略 、排它日历、数据持久化
  15. 利用windbg分析程序崩溃生成的dmp文件
  16. DEM高程数据的获取和应用(全国DEM数据可直接下载)
  17. php redis入门指南,redis入门指南(四)—— redis如何节省空间
  18. 【聚焦群落生态学】统计方法回归和混合效应模型、多元统计分析技术及结构方程等数量分析方法
  19. 安卓游戏 我叫mt 3.5.4.0 3540,data.dat 文件解包记录
  20. 今天身边的一个好友想的一个点子,可能会颠覆传统电商网,称为线上商店和线下商店的最后收割者

热门文章

  1. lzw编码过程详解_编码拓展——封装、编码、码率
  2. 双代号网络图节点编号原则_『干货』二级建造师考试高频考点 双代号网络图的详细解析...
  3. mpvue 微信小程序api_第三方框架与原生微信小程序开发框架性能之比较 | Q荐读...
  4. 无源定位之时差估计的精确时差估计算法(ETDE)及MATLAB实现程序
  5. 有负权重边的图可以有拉普拉斯矩阵吗?
  6. 数据中台应用实战50篇(二)-中台解决方案本质在解决什么问题?
  7. tableau可视化数据分析60讲(二十)-tableau格式设置
  8. 图像处理特征不变算子系列之KLT算子
  9. 非负矩阵分解中基于L1和L2范式的稀疏性约束
  10. 数据分析利器--Pandas