JUC 并发类概览
JUC 并发类及并发相关类概览,持续补充...
AQS
内部有两个队列,一个等待队列(前后节点),一个条件队列(后继节点),其实是通过链表方式实现;
等待队列是双向链表;条件队列是单向链表;条件队列如果被唤醒,将后接到等待队列上;
通过内部持有的 state,加以模板模式,提供了两种资源争抢模式:排他、共享;而在争抢时,又辅以公平、非公平竞争的考虑;
排他与共享分别通过子类实现的:boolean tryAcquire和(tryAcquireShared(x) >= 0来判断获取资源是否成功,同时排他限制:state 只能被一个线程修改(一般修改为 1,CAS(0,1),可重入);而共享则支持多线程同时更改 state 值(被多个线程获取);
获取时要考虑是否关注中断唤醒行为,对应方法名后缀:-Interruptible,关注则抛异常,不关注则清除线程的中断标记位记录,继续挂起直到获取成功,再中断线程;
总的下来,分支考虑就是:资源类型(是否排他)-> 是否公平 -> 是否关注中断(每一个都是两个方向);
释放资源时,排他类型需要判断是否当前线程,而共享类型不需要判断线程,只关注资源池;排他类型会唤醒等待队列的下一个节点,而共享则会通过级联方式传递信号,从 head 开始唤醒,直到资源被新唤醒的线程抢光才停止;
线程的挂起是通过LockSupport.park(thread),支持限时挂起;
state 释放导致等待队列判断,进而唤醒。限时挂起必定支持中断响应;
条件队列因为初始时是通过new ConditionObject(),可以多次创建,所以支持多个条件队列,使用同一个对象即是同一个条件队列;被唤醒时会执行 state 的资源获取,获取不到则进入等待队列;同样支持是否中断关注;而条件队列的中断有两种情况,一种在条件队列上被中断唤醒,一种是在进入等待队列后被中断唤醒;
AQS 主要是资源 state 的 CAS 并发及线程中断挂起,排队的控制AQLS
state 的类型为 long,扩展了并发数(未来扩展)。其他与 AQS 相同。
long 需要关注缓存行问题。ReentrantLock
基于 AQS 实现的锁,设置 state = 1;支持公平与非公平(判断队列是否有等待线程);支持重入,state 递增;竞争时只有state = 0才获取锁成功,否则进入等待队列;
支持 condition 的 await 和 signal。CopyOnWriteArrayList
与 AQS 无关,使用的 synchronized 保证同步安全;当发生添加行为时,会将原数组拷贝一份进行添加,然后更新引用;当发生指定索引添加时,会定位索引,分两步进行拷贝(索引前、索引后);适合读多写少场景;addIfAbsent 会先判断(无同步锁),然后拷贝(有同步锁),判断时会先拷贝一份快照,在更新索引时判断快照是否最新,是则直接使用,否则重新拷贝;CopyOnWriteArraySet
底层使用了 CopyOnWriteArrayList。唯一性的添加则是使用了 addIfAbsent。其他大部分方法直接调用了 CopyOnWriteArrayList 的类似方法;CountDownLatch
使用了 AQS,初始化大小即为 state,每次 countDown 都是对state - 1,而 await 则是在判断getState() == 0 ? 1 : -1不通过挂起在队列中,所以有多少 state 则其会被唤醒 state 次,然后重新挂起,直到state = 0;ArrayBlockingQueue
未直接使用或继承 AQS,而是通过使用 ReentrantLock 和 Condition 来完成多线程同步与挂起;
内部使用数组存储元素,但不会扩展,实现了环形队列存储,队列元素增加offer及获取poll都使用 lock 进行同步;
当添加成功时,进行notEmpty.signal()通知,唤醒获取失败的线程(notEmpty.await())处理;
当获取成功时,进行notFull.signal()通知,唤添加失败的线程(notFulll.await())处理;
offer(E)添加返回true/false;add(E)内部调用offer,返回 false 则抛异常;put自实现,无法添加则阻塞;
poll()获取返回E/null,take自实现,如果获取不到则阻塞挂起;
任何添加或获取成功,相应的都会进行notEmpty与notFull通知,而失败则进入相反的队列挂起;
ArrayBlockingQueue 的并发遍历实现是通过队列延展实现的(就是一个队列,不断的翻滚);类似于环形队列
JUC 并发类概览的更多相关文章
- JUC源码分析-集合篇:并发类容器介绍
JUC源码分析-集合篇:并发类容器介绍 同步类容器是 线程安全 的,如 Vector.HashTable 等容器的同步功能都是由 Collections.synchronizedMap 等工厂方法去创 ...
- 多线程进阶——JUC并发编程之CountDownLatch源码一探究竟
1.学习切入点 JDK的并发包中提供了几个非常有用的并发工具类. CountDownLatch. CyclicBarrier和 Semaphore工具类提供了一种并发流程控制的手段.本文将介绍Coun ...
- JUC并发编程学习笔记
JUC并发编程学习笔记 狂神JUC并发编程 总的来说还可以,学到一些新知识,但很多是学过的了,深入的部分不多. 线程与进程 进程:一个程序,程序的集合,比如一个音乐播发器,QQ程序等.一个进程往往包含 ...
- JUC原子操作类与乐观锁CAS
JUC原子操作类与乐观锁CAS 硬件中存在并发操作的原语,从而在硬件层面提升效率.在intel的CPU中,使用cmpxchg指令.在Java发展初期,java语言是不能够利用硬件提供的这些便利来提 ...
- JUC并发编程与高性能内存队列disruptor实战-上
JUC并发实战 Synchonized与Lock 区别 Synchronized是Java的关键字,由JVM层面实现的,Lock是一个接口,有实现类,由JDK实现. Synchronized无法获取锁 ...
- 多线程JUC并发篇常见面试详解
@ 目录 1.JUC 简介 2.线程和进程 3.并非与并行 4.线程的状态 5.wait/sleep的区别 6.Lock 锁(重点) 1.Lock锁 2.公平非公平: 3.ReentrantLock ...
- 再谈AbstractQueuedSynchronizer:基于AbstractQueuedSynchronizer的并发类实现
公平模式ReentrantLock实现原理 前面的文章研究了AbstractQueuedSynchronizer的独占锁和共享锁,有了前两篇文章的基础,就可以乘胜追击,看一下基于AbstractQue ...
- 再谈AbstractQueuedSynchronizer3:基于AbstractQueuedSynchronizer的并发类实现
公平模式ReentrantLock实现原理 前面的文章研究了AbstractQueuedSynchronizer的独占锁和共享锁,有了前两篇文章的基础,就可以乘胜追击,看一下基于AbstractQue ...
- Java 并发编程-再谈 AbstractQueuedSynchronizer 3 :基于 AbstractQueuedSynchronizer 的并发类实现
公平模式ReentrantLock实现原理 前面的文章研究了AbstractQueuedSynchronizer的独占锁和共享锁,有了前两篇文章的基础,就可以乘胜追击,看一下基于AbstractQue ...
随机推荐
- Masterwoker模式
1 public class Task { 2 3 private int id; 4 private int price ; 5 public int getId() { 6 return id; ...
- P1055_ISBN号码(JAVA语言)
题目描述 每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字.1位识别码和3位分隔符, 其规定格式如x-xxx-xxxxx-x,其中符号-就是分隔符(键盘上的减号), 最后一位是 ...
- 攻防世界 maze NJUPT CTF 2017
迷宫题 1 __int64 __fastcall main(__int64 a1, char **a2, char **a3) 2 { 3 signed __int64 mid_i; // rbx 4 ...
- 使用C# (.NET Core) 实现模板方法模式 (Template Method Pattern)
本文的概念内容来自深入浅出设计模式一书. 项目需求 有一家咖啡店, 供应咖啡和茶, 它们的工序如下: 咖啡: 茶: 可以看到咖啡和茶的制作工序是差不多的, 都是有4步, 其中有两步它们两个是一样的, ...
- Java例题_31 逆序输出数组的值
1 /*31 [程序 31 数组逆序] 2 题目:将一个数组逆序输出. 3 程序分析:用第一个与最后一个交换. 4 */ 5 6 /*分析 7 * 第一种方法:找到这个数组的中间下标,然后交换两端的数 ...
- Android Studio 通过 ListView 学习 ArrayAdapte
ListView •前言 ListView 绝对可以称得上是 Android 中最常用的控件之一,几乎所有的应用程序都会用到它. 由于手机屏幕空间有限,能够一次性在屏幕上显示的内容并不多,当我们的程序 ...
- vue实现拖拽排序
基于vue实现列表拖拽排序的效果 在日常开发中,特别是管理端,经常会遇到要实现拖拽排序的效果:这里提供一种简单的实现方案. 此例子基于vuecli3 首先,我们先了解一下js原生拖动事件: 在拖动目标 ...
- day-03-基础数据类型
基础数类型总览 10203 123 3340 int +- * / 等等 '今天吃了没?' str 存储少量的数据,+ *int 切片, 其他操作方法 True False bool 判断真假 [12 ...
- 如何优雅地学习计算机2<-->Helloworld
0.导入 在进行粗略的学习计算机底层知识和变量后,我们来开始编写年轻人的第一个程序--Helloworld. 我们需要用到的工具有:1.Dev-C++(也可以使用其他软件)2.脑子(最重要) ...
- Java(195-214)【final、权限、内部类】
1.final关键字的概念与四种方法 今天是基础学习的最后一天!~ 2.final关键字用来修饰一个类 3.final关键字来修饰成员方法 4.final用于修饰局部变量 package cn.itc ...