天穹之边,浩瀚之挚,眰恦之美; 悟心悟性,虎头蛇尾,惟善惟道! —— 朝槿《朝槿兮年说》
写在结尾
在并发编程畛域,有两大外围问题:一个是互斥,即同一时刻只容许一个线程访问共享资源;另一个是同步,即线程之间如何通信、合作。
次要起因是,对于多线程实现实现并发,始终以来,多线程都存在2个问题:
- 线程之间内存共享,须要通过加锁进行管制,然而加锁会导致性能降落,同时简单的加锁机制也会减少编程编码难度
- 过多线程造成线程之间的上下文切换,导致效率低下
因而,在并发编程畛域中,始终有一个很重要的设计准则: “ 不要通过内存共享来实现通信,而应该通过通信来实现内存共享。”
简略来说,就是尽可能通过音讯通信,而不是内存共享来实现过程或者线程之间的同步。
关健术语
本文用到的一些要害词语以及罕用术语,次要如下:
- 并发(Concurrent): 在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行结束之间,且这几个程序都是在同一个处理机上运行。
- 并行(Parallel): 当零碎有一个以上CPU时,当一个CPU执行一个过程时,另一个CPU能够执行另一个过程,两个过程互不抢占CPU资源,能够同时进行。
- 信号量(Semaphore): 是在多线程环境下应用的一种设施,是能够用来保障两个或多个要害代码段不被并发调用,也是作零碎用来解决并发中的互斥和同步问题的一种办法。
- 信号量机制(Semaphores): 用来解决同步/互斥的问题的,它是1965年,荷兰学者 Dijkstra提出了一种行之有效的实现过程互斥与同步的办法。
- 管程(Monitor) : 个别是指治理共享变量以及对共享变量的操作过程,让它们反对并发的一种机制。
- 互斥(Mutual Exclusion):一个公共资源同一时刻只能被一个过程或线程应用,多个过程或线程不能同时应用公共资源。即就是同一时刻只容许一个线程访问共享资源的问题。
- 同步(Synchronization):两个或两个以上的过程或线程在运行过程中协同步调,按预约的先后秩序运行。即就是线程之间如何通信、合作的问题。
- 对象池(Object Pool): 指的是一次性创立出 N 个对象,之后所有的线程反复利用这 N 个对象,当然对象在被开释前,也是不容许其余线程应用的, 个别指保留实例对象的容器。
根本概述
在Java畛域中,咱们能够将锁大抵分为基于Java语法层面(关键词)实现的锁和基于JDK层面实现的锁。
在Java畛域中, 尤其是在并发编程畛域,对于多线程并发执行始终有两大外围问题:同步和互斥。其中:
- 互斥(Mutual Exclusion):一个公共资源同一时刻只能被一个过程或线程应用,多个过程或线程不能同时应用公共资源。即就是同一时刻只容许一个线程访问共享资源的问题。
- 同步(Synchronization):两个或两个以上的过程或线程在运行过程中协同步调,按预约的先后秩序运行。即就是线程之间如何通信、合作的问题。
针对对于这两大外围问题,利用管程是可能解决和实现的,因而能够说,管程是并发编程的万能钥匙。
尽管,Java在基于语法层面(synchronized 关键字)实现了对管程技术,然而从应用形式和性能上来说,内置锁(synchronized 关键字)的粒度绝对过大,不反对超时和中断等问题。
为了补救这些问题,从JDK层面对其“反复造轮子”,在JDK外部对其从新设计和定义,甚至实现了新的个性。
在Java畛域中,从JDK源码剖析来看,基于JDK层面实现的锁大抵次要能够分为以下4种形式:
- 基于Lock接口实现的锁:JDK1.5版本提供的ReentrantLock类
- 基于ReadWriteLock接口实现的锁:JDK1.5版本提供的ReentrantReadWriteLock类
- 基于AQS根底同步器实现的锁:JDK1.5版本提供的并发相干的同步器Semaphore,CyclicBarrier以及CountDownLatch等
- 基于自定义API操作实现的锁:JDK1.8版本中提供的StampedLock类
从浏览源码不难发现,在Java SDK 并发包次要通过AbstractQueuedSynchronizer(AQS)实现多线程同步机制的封装与定义,而通过Lock 和 Condition 两个接口来实现管程,其中 Lock 用于解决互斥问题,Condition 用于解决同步问题。
一.AQS根底同步器根本实践
在Java畛域中,同步器是专门为多线程并发设计的同步机制,次要是多线程并发执行时线程之间通过某种共享状态来实现同步,只有当状态满足这种条件时线程才往下执行的一种同步机制。
一个规范的AQS同步器次要有同步状态机制,期待队列,条件队列,独占模式,共享模式等五大外围因素组成。
在Java畛域中,JDK的JUC(java.util.concurrent.)包中提供了各种并发工具,然而大部分同步工具的实现基于AbstractQueuedSynchronizer类实现,其内部结构次要如下:
- 同步状态机制(Synchronization Status):次要用于实现锁(Lock)机制,是指同步状态,其要求对于状态的更新必须原子性的
- 期待队列(Wait Queue):次要用于寄存期待线程获取到的锁资源,并且把线程保护到一个Node(节点)外面和保护一个非阻塞的CHL Node FIFO(先进先出)队列,次要是采纳自旋锁+CAS操作来保障节点插入和移除的原子性操作。
- 条件队列(Condition Queue):用于实现锁的条件机制,个别次要是指替换“期待-告诉”工作机制,次要是通过ConditionObject对象实现Condition接口提供的办法实现。
- 独占模式(Exclusive Mode):次要用于实现独占锁,次要是基于动态外部类Node的常量标记EXCLUSIVE来标识该节点是独占模式
- 共享模式(Shared Mode):次要用于实现共享锁,次要是基于动态外部类Node的常量标记SHARED来标识该节点是共享模式
咱们能够失去一个比拟通用的并发同步工具根底模型,大抵蕴含如下几个内容,其中:
- 条件变量(Conditional Variable): 利用线程间共享的变量进行同步的一种工作机制
- 共享变量((Shared Variable)):个别指对象实体对象的成员变量和属性
- 阻塞队列(Blocking Queue):共享变量(Shared Variable)及其对共享变量的操作对立封装
- 期待队列(Wait Queue):每个条件变量都对应有一个期待队列(Wait Queue),外部须要实现入队操作(Enqueue)和出队操作(Dequeue)办法
- 变量状态形容机(Synchronization Status):形容条件变量和共享变量之间状态变动,又能够称其为同步状态
- 工作模式(Operation Mode): 线程资源具备排他性,因而定义独占模式和共享模式两种工作模式
综上所述,条件变量和期待队列的作用是解决线程之间的同步问题;共享变量与阻塞队列的作用是解决线程之间的互斥问题。
二. JDK显式锁对立概念模型
在并发编程畛域,有两大外围问题:一个是互斥,即同一时刻只容许一个线程访问共享资源;另一个是同步,即线程之间如何通信、合作。
综合Java畛域中的并发锁的各种实现与利用剖析来看,一把锁或者一种锁,基本上都会蕴含以下几个方面:
- 锁的同步器工作机制:次要是思考共享模式还是独享模式,是否反对超时机制,以及是否反对超时机制?
- 锁的同步器工作模式:次要是基于AQS根底同步器封装外部同步器,是否思考偏心/非偏心模式?
- 锁的状态变量机制: 次要锁的状态设置,是否共享状态变量?
- 锁的队列封装定义:次要是指期待队列和条件队列,是否须要条件队列或者期待队列定义?
- 锁的底层实现操作: 次要是指底层CL锁和CAS操作,是否须要思考自旋锁或者CAS操作实例对象办法?
- 锁的组合实现新锁: 次要是基于独占锁和共享锁,是否思考对应API自定义操作实现?
综上所述,大抵能够根据上述这些方向,咱们便能够分明️晓得Java畛域中各种锁实现的根本实践时和实现思维。
四.ReentrantReadWriteLock(读写锁)的设计与实现
在Java畛域中,ReentrantReadWriteLock(读写锁)是针对于Java多线程并发管制中引入一个共享锁定义读操作与独占锁定义读操作等场景独特组合形成一把锁来进步并发,次要是基于内置的AQS根底形象队列同步器实现的一种并发管制工具类。
通过ReentrantReadWriteLock类能获取读锁和写锁,它的读锁是能够多线程共享的共享锁,而它的写锁是排他锁,在被占时不容许其余线程再抢占操作。
1. 设计思维
一般来说,在一些非凡的场景中,比方对于数据的读和写操作,为进步并发性能,总会引入共享锁和独享锁来独特组成一把锁,通常状况下,咱们把这类锁成为读写锁(ReadWriteLock) 。
简略来说,就是次要思考读和写操作,读操作不会批改数据,能够利用多个线程进行读操作,个别采纳共享锁实现;而写操作会扭转数据自身,只能容许一个线程进行操作,因而采纳独享锁实现。
读写锁(ReadWriteLock) 最大的一个特点就是在外部保护一对锁,一把读锁(ReadLock) ,一把写锁(WriteLock) 。其中,对于线程持有的状况来说,简略能够总结为“读共享,写独占”。
1.1 读写锁的根本实践
尽管读写锁(ReadWriteLock) 之间是有关系的:同一时刻不容许读锁和写锁同时被抢占,二者之间是互斥的。
假如当初有N个线程,次要从T(1),T(2),...,始终到T(N)个线程,在读写锁的操作状况如下,其中:
- 多读模式(多读共享):T(N) 个线程能够同时把持并获取读锁,假如T(1)线程胜利获取并持有读锁,T(2)线程和后续的T(N)个线程仍然能够胜利获取读锁,即便T(1)线程没有开释持有的读锁。
- 读写模式(读写互斥):假如T(1)线程胜利获取并持有读锁,T(2)线程和后续的T(N)个线程便不能胜利获取且持有写锁,除非T(1)线程曾经开释持有的读锁。
- 独写模式(单写独占):假如T(1)线程胜利获取并持有写锁,T(2)线程和后续的T(N)个线程便不能胜利获取且持有读锁和写锁,只能期待期待T(1)线程开释完持有的写锁,能力持续往下执行。
从肯定意义上讲,依据读写锁操作的状况的性质剖析,获取读锁和写锁的条件能够大抵总结为:
- 获取读锁的条件:以后任何线程没有胜利获取且曾经持有写锁的状况,才可能获取并持有读锁。
- 获取写锁的条件:以后任何线程没有胜利获取且曾经持有写锁和读锁的状况,才可能获取并持有写锁。
然而在某些状况下,可能存在某个线程曾经获取并持有读锁,心愿可能获取写锁,并且在曾经开释读锁时,通常状况下咱们称之为读写锁的降级。
当然,有降级就会有降级,与之对应的就是读写锁的降级,次要形容的是某个线程曾经获取并持有写锁,心愿可能获取读锁,并且曾经开释写锁。
一般来说,对于读写锁的降级与降级,咱们个别须要留神的以下两个问题,其中:
- 读写锁的降级:指的是读锁降级为写锁的状况,须要满足某个线程必须是惟一领有读锁的线程的条件,否则无奈降级。
读写锁的降级:指的是写锁降级为读锁的状况,没有什么条件限度,写锁是独占锁,其持有线程是惟一的且不会存在读锁持有线程的状况,能够间接平滑降级读锁。
1.2 读写锁的实现思维
ReentrantReadWriteLock最早是在JDK1.5版本中提供的,从设计思维上来看,次要包含同步器的工作模式,读锁和写锁等3个外围因素。其中:
- 实现ReadWriteLock接口 :次要基于ReadWriteLock接口API实现对应办法,次要是实现writeLock()办法和readLock() 办法,其中writeLock()办法示意获取写锁,readLock() 办法示意获取读锁。
- 同步器的工作模式:基于AQS根底形象队列同步器封装内置实现一个动态的内置同步器抽象类,而后基于这个抽象类别离实现了偏心同步器和非偏心同步器,用来指定和形容同步器工作模式是偏心模式还是非偏心模式。
- 偏心/非偏心模式:次要形容的是多个线程在同时获取锁时是否依照先到先得的程序获取锁,如果是则为偏心模式,否则为非偏心模式。
- 内置两个动态私有外部类:定义了读锁和写锁动态私有外部类,并且都反对偏心/非偏心模式,实质都是基于AQS根底形象队列同步器实现。
保护共享状态变量: 次要是基于一个AQS根底形象队列同步器来实现读锁和写锁,要求共用一个共享状态变量。
2. 根本实现
在ReentrantReadWriteLock类在JDK1.8版本中,对于ReentrantReadWriteLock的根本实现如下:
public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable { private static final long serialVersionUID = -6992448646407690164L; /** ReentrantReadWriteLock锁-外部ReadLock类 */ private final ReentrantReadWriteLock.ReadLock readerLock; /** ReentrantReadWriteLock锁-外部WriteLock类 */ private final ReentrantReadWriteLock.WriteLock writerLock; /** ReentrantReadWriteLock锁-外部同步器 */ final Sync sync; /** ReentrantReadWriteLock锁-基于AQS封装外部同步器 */ abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 6317671515068378041L; /** ReentrantReadWriteLock锁-共用状态变量封装-begin*/ /** ReentrantReadWriteLock锁-共用状态变量封装-共享状态挪动位数16 */ static final int SHARED_SHIFT = 16; /** ReentrantReadWriteLock锁-共用状态变量封装-读锁每次加锁的状态大小*/ static final int SHARED_UNIT = (1 << SHARED_SHIFT); /** ReentrantReadWriteLock锁-共用状态变量封装-读锁每次加锁的最大次数*/ static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; /** ReentrantReadWriteLock锁-共用状态变量封装-写锁的掩码*/ static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; /** ReentrantReadWriteLock锁-共用状态变量封装-本地存储读锁次数*/ private transient ThreadLocalHoldCounter readHolds; /** ReentrantReadWriteLock锁-共用状态变量封装-读锁的状态码值*/ private transient HoldCounter cachedHoldCounter; /** ReentrantReadWriteLock锁-共用状态变量封装-线程变量*/ private transient Thread firstReader = null; /** ReentrantReadWriteLock锁-共用状态变量封装-首次读锁次数*/ private transient int firstReaderHoldCount; /** ReentrantReadWriteLock锁-共用状态变量封装-end*/ Sync() { readHolds = new ThreadLocalHoldCounter(); setState(getState()); // ensures visibility of readHolds } /** ReentrantReadWriteLock锁-读锁标记*/ abstract boolean readerShouldBlock(); /** ReentrantReadWriteLock锁-读锁标记*/ abstract boolean writerShouldBlock(); //... 其余代码 } /** ReentrantReadWriteLock锁-无参数结构(默认非偏心模式) */ public ReentrantReadWriteLock() { this(false); } /** ReentrantReadWriteLock锁-有参数结构(可选偏心/非偏心模式) */ public ReentrantReadWriteLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); readerLock = new ReadLock(this); writerLock = new WriteLock(this); } /** ReentrantReadWriteLock锁-获取写锁 */ public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } /** ReentrantReadWriteLock锁-获取读锁 */ public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; } /** ReentrantReadWriteLock锁-实例化Unsafe反对 */ private static final sun.misc.Unsafe UNSAFE; /** ReentrantReadWriteLock锁-线程偏移量 */ private static final long TID_OFFSET; /** ReentrantReadWriteLock锁-获取线程变量 */ static final long getThreadId(Thread thread) { return UNSAFE.getLongVolatile(thread, TID_OFFSET); } /** ReentrantReadWriteLock锁-反射机制实例化Unsafe */ static { try { UNSAFE = sun.misc.Unsafe.getUnsafe(); Class<?> tk = Thread.class; TID_OFFSET = UNSAFE.objectFieldOffset (tk.getDeclaredField("tid")); } catch (Exception e) { throw new Error(e); } } }
- 外部同步器:基于AQS根底同步器封装和定义了一个动态外部Sync抽象类
- 同步器工作模式:提供了 2个构造方法,其中无参数构造方法示意的是默认的工作模式,有参数构造方法次要根据参数来实现指定的工作模式
- 偏心/非偏心模式:次要是基于Sync抽象类封装NonfairSync非偏心同步器和封装NonfairSync非偏心同步器来实现。
- 内置两个外部类:次要是实现了ReadLock类和WriteLock类,其中ReadLock类对应着读锁,WriteLock类对应着写锁。
2.1 基于AQS同步器封装动态外部Sync抽象类
/** ReentrantReadWriteLock锁-基于AQS封装外部同步器 */abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 6317671515068378041L; /** ReentrantReadWriteLock锁-共用状态变量封装-begin */ /** ReentrantReadWriteLock锁-共用状态变量封装-共享状态挪动位数16 */ static final int SHARED_SHIFT = 16; /** ReentrantReadWriteLock锁-共用状态变量封装-读锁每次加锁的状态大小*/ static final int SHARED_UNIT = (1 << SHARED_SHIFT); /** ReentrantReadWriteLock锁-共用状态变量封装-读锁每次加锁的最大次数*/ static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; /** ReentrantReadWriteLock锁-共用状态变量封装-写锁的掩码*/ static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; /** ReentrantReadWriteLock锁-共用状态变量封装-本地存储读锁次数*/ private transient ThreadLocalHoldCounter readHolds; /** ReentrantReadWriteLock锁-共用状态变量封装-读锁的状态码值*/ private transient HoldCounter cachedHoldCounter; /** ReentrantReadWriteLock锁-共用状态变量封装-线程变量*/ private transient Thread firstReader = null; /** ReentrantReadWriteLock锁-共用状态变量封装-首次读锁次数*/ private transient int firstReaderHoldCount; /** ReentrantReadWriteLock锁-共用状态变量封装-end*/ Sync() { readHolds = new ThreadLocalHoldCounter(); setState(getState()); // ensures visibility of readHolds } /** ReentrantReadWriteLock锁-读锁标记*/ abstract boolean readerShouldBlock(); /** ReentrantReadWriteLock锁-读锁标记*/ abstract boolean writerShouldBlock(); /** ReentrantReadWriteLock锁-独占模式获取读锁*/ protected final boolean tryRelease(int releases) { if (!isHeldExclusively()) throw new IllegalMonitorStateException(); int nextc = getState() - releases; boolean free = exclusiveCount(nextc) == 0; if (free) setExclusiveOwnerThread(null); setState(nextc); return free; } /** ReentrantReadWriteLock锁-独占模式开释锁*/ protected final boolean tryAcquire(int acquires) { Thread current = Thread.currentThread(); int c = getState(); int w = exclusiveCount(c); if (c != 0) { // (Note: if c != 0 and w == 0 then shared count != 0) if (w == 0 || current != getExclusiveOwnerThread()) return false; if (w + exclusiveCount(acquires) > MAX_COUNT) throw new Error("Maximum lock count exceeded"); // Reentrant acquire setState(c + acquires); return true; } if (writerShouldBlock() || !compareAndSetState(c, c + acquires)) return false; setExclusiveOwnerThread(current); return true; } /** ReentrantReadWriteLock锁-共享模式开释锁*/ protected final boolean tryReleaseShared(int unused) { Thread current = Thread.currentThread(); if (firstReader == current) { // assert firstReaderHoldCount > 0; if (firstReaderHoldCount == 1) firstReader = null; else firstReaderHoldCount--; } else { HoldCounter rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) rh = readHolds.get(); int count = rh.count; if (count <= 1) { readHolds.remove(); if (count <= 0) throw unmatchedUnlockException(); } --rh.count; } for (;;) { int c = getState(); int nextc = c - SHARED_UNIT; if (compareAndSetState(c, nextc)) return nextc == 0; } } /** ReentrantReadWriteLock锁-共享模式获取锁*/ protected final int tryAcquireShared(int unused) { Thread current = Thread.currentThread(); int c = getState(); if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return -1; int r = sharedCount(c); if (!readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) { if (r == 0) { firstReader = current; firstReaderHoldCount = 1; } else if (firstReader == current) { firstReaderHoldCount++; } else { HoldCounter rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) cachedHoldCounter = rh = readHolds.get(); else if (rh.count == 0) readHolds.set(rh); rh.count++; } return 1; } return fullTryAcquireShared(current); } /** ReentrantReadWriteLock锁-共享模式获取锁*/ final int fullTryAcquireShared(Thread current) { HoldCounter rh = null; for (;;) { int c = getState(); if (exclusiveCount(c) != 0) { if (getExclusiveOwnerThread() != current) return -1; // else we hold the exclusive lock; blocking here // would cause deadlock. } else if (readerShouldBlock()) { // Make sure we're not acquiring read lock reentrantly if (firstReader == current) { // assert firstReaderHoldCount > 0; } else { if (rh == null) { rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) { rh = readHolds.get(); if (rh.count == 0) readHolds.remove(); } } if (rh.count == 0) return -1; } } if (sharedCount(c) == MAX_COUNT) throw new Error("Maximum lock count exceeded"); if (compareAndSetState(c, c + SHARED_UNIT)) { if (sharedCount(c) == 0) { firstReader = current; firstReaderHoldCount = 1; } else if (firstReader == current) { firstReaderHoldCount++; } else { if (rh == null) rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) rh = readHolds.get(); else if (rh.count == 0) readHolds.set(rh); rh.count++; cachedHoldCounter = rh; // cache for release } return 1; } } } /** ReentrantReadWriteLock锁-判断是否独占模式*/ protected final boolean isHeldExclusively() { return getExclusiveOwnerThread() == Thread.currentThread(); } // Methods relayed to outer class /** ReentrantReadWriteLock锁-定义条件变量*/ final ConditionObject newCondition() { return new ConditionObject(); } /** ReentrantReadWriteLock锁-获取以后锁的持有者*/ final Thread getOwner() { // Must read state before owner to ensure memory consistency return ((exclusiveCount(getState()) == 0) ? null : getExclusiveOwnerThread()); } /** ReentrantReadWriteLock锁-获取读锁次数统计*/ final int getReadLockCount() { return sharedCount(getState()); } /** ReentrantReadWriteLock锁-判断是否是写锁*/ final boolean isWriteLocked() { return exclusiveCount(getState()) != 0; } /** ReentrantReadWriteLock锁-获取写锁持有次数统计*/ final int getWriteHoldCount() { return isHeldExclusively() ? exclusiveCount(getState()) : 0; } /** ReentrantReadWriteLock锁-获取读锁次持有数统计*/ final int getReadHoldCount() { if (getReadLockCount() == 0) return 0; Thread current = Thread.currentThread(); if (firstReader == current) return firstReaderHoldCount; HoldCounter rh = cachedHoldCounter; if (rh != null && rh.tid == getThreadId(current)) return rh.count; int count = readHolds.get().count; if (count == 0) readHolds.remove(); return count; } /** ReentrantReadWriteLock锁-获取读锁*/ final boolean tryReadLock() { Thread current = Thread.currentThread(); for (;;) { int c = getState(); if (exclusiveCount(c) != 0 && getExclusiveOwnerThread() != current) return false; int r = sharedCount(c); if (r == MAX_COUNT) throw new Error("Maximum lock count exceeded"); if (compareAndSetState(c, c + SHARED_UNIT)) { if (r == 0) { firstReader = current; firstReaderHoldCount = 1; } else if (firstReader == current) { firstReaderHoldCount++; } else { HoldCounter rh = cachedHoldCounter; if (rh == null || rh.tid != getThreadId(current)) cachedHoldCounter = rh = readHolds.get(); else if (rh.count == 0) readHolds.set(rh); rh.count++; } return true; } } } /** ReentrantReadWriteLock锁-获取写锁*/ final boolean tryWriteLock() { Thread current = Thread.currentThread(); int c = getState(); if (c != 0) { int w = exclusiveCount(c); if (w == 0 || current != getExclusiveOwnerThread()) return false; if (w == MAX_COUNT) throw new Error("Maximum lock count exceeded"); } if (!compareAndSetState(c, c + 1)) return false; setExclusiveOwnerThread(current); return true; } /** ReentrantReadWriteLock锁-流解决*/ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); readHolds = new ThreadLocalHoldCounter(); setState(0); // reset to unlocked state } /** ReentrantReadWriteLock锁-获取状态*/ final int getCount() { return getState(); }}
实现形式: 次要是基于AQS根底同步器来实现,其中封装形象了readerShouldBlock()办法和writerShouldBlock()办法,用于标记以后申请的线程是获取什么类型的锁。其中:
- readerShouldBlock()办法:根据标记返回的是true,标记线程获取的是ReadLock锁
- writerShouldBlock()办法:根据标记返回的是true,标记线程获取的是WriteLock锁
- 保护共用状态变量: 对于共享状态变量的实现,次要是在外部的同步器中Sync类中定义HoldCounter类和ThreadLocalHoldCounter类实现的,其中定义了一堆常量,统计读写锁状态值的sharedCount()办法和exclusiveCount()办法。
读写锁的次要办法: 次要是提供了tryReadLock()办法和tryWriteLock()办法,其中:
- tryReadLock()办法:获取读锁办法,外围解决是自旋+compareAndSetState()办法来解决
- tryWriteLock()办法:获取写锁办法,外围解决是通过compareAndSetState()办法来解决
读写锁的获取形式:基于AQS根底同步器来实现对于共享模式和独享模式两种状况,都提供了对应的办法。其中:
- tryAcquire()办法:独享模式获取锁办法,这里次要针对WriteLock锁,外围解决是通过AQS根底同步器中compareAndSetState()办法来解决,实现状态变量的操作
- tryAcquireShared() 办法:共享模式获取锁办法,这里次要对应ReadLock锁,外围解决是通过AQS根底同步器中compareAndSetState()办法来解决,实现状态变量的操作
读写锁的开释形式:基于AQS根底同步器来实现对于共享模式和独享模式两种状况,都提供了对应的办法。其中:
- tryRelease(int releases) 办法:独享模式开释锁办法
- tryReleaseShared(int unused) 办法:共享模式开释锁办法,外围解决是自旋+compareAndSetState()办法来解决
其余办法:次要还提供了一些比拟惯例的办法,其中:
- getCount() 办法:次要是基于AQS根底同步器来获取状态变量
- getOwner()办法:次要是用于获取以后锁的持有者,个别是线程对象,依据_exclusiveCount_(getState()) == 0来判断,条件成立就默认为null; 否则,通过AQS根底同步器中的getExclusiveOwnerThread()办法来获取。
- getReadLockCount() 办法:用于获取某个线程对于ReadLock锁的数量,次要是统计次数
- isWriteLocked() 办法:用于判断线程是否曾经获取并持有WriteLock锁
- getWriteHoldCount()办法:用于获取线程对于WriteLock锁的持有状况,次要是统计次数
- getReadHoldCount() 办法:用于获取线程对于WriteLock锁的持有状况,次要是统计次数
- isHeldExclusively() 办法:用于判断是否独占模式
- unmatchedUnlockException()办法:封装一个异样解决信息,次要是指定IllegalMonitorStateException
2.2 基于Sync抽象类封装共享状态变量
/** ReentrantReadWriteLock锁-基于AQS封装外部同步器 */abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 6317671515068378041L; /** ReentrantReadWriteLock锁-共用状态变量封装-begin*/ /** ReentrantReadWriteLock锁-共用状态变量封装-共享状态挪动位数16 */ static final int SHARED_SHIFT = 16; /** ReentrantReadWriteLock锁-共用状态变量封装-读锁每次加锁的状态大小*/ static final int SHARED_UNIT = (1 << SHARED_SHIFT); /** ReentrantReadWriteLock锁-共用状态变量封装-读锁每次加锁的最大次数*/ static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; /** ReentrantReadWriteLock锁-共用状态变量封装-写锁的掩码*/ static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; /** ReentrantReadWriteLock锁-共用状态变量封装-本地存储读锁次数*/ private transient ThreadLocalHoldCounter readHolds; /** ReentrantReadWriteLock锁-共用状态变量封装-读锁的状态码值*/ private transient HoldCounter cachedHoldCounter; /** ReentrantReadWriteLock锁-共用状态变量封装-线程变量*/ private transient Thread firstReader = null; /** ReentrantReadWriteLock锁-共用状态变量封装-首次读锁次数*/ private transient int firstReaderHoldCount; /** ReentrantReadWriteLock锁-共用状态变量封装-end*/ /** ReentrantReadWriteLock锁-共用状态变量封装-构造方法*/ Sync() { readHolds = new ThreadLocalHoldCounter(); setState(getState()); // ensures visibility of readHolds } /** ReentrantReadWriteLock锁-共用状态变量封装-读锁的状态码值*/ static int sharedCount(int c) { return c >>> SHARED_SHIFT; } /** ReentrantReadWriteLock锁-共用状态变量封装-写锁的状态码值*/ static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; } /** ReentrantReadWriteLock锁-共用状态变量-统计计数器 */ static final class HoldCounter { int count = 0; // Use id, not reference, to avoid garbage retention final long tid = getThreadId(Thread.currentThread()); } /** ReentrantReadWriteLock锁-共用状态变量-本地存储统计正本 */ static final class ThreadLocalHoldCounter extends ThreadLocal<HoldCounter> { public HoldCounter initialValue() { return new HoldCounter(); } } //... 其余代码}
实现形式: 次要是在外部的同步器中Sync类中定义HoldCounter类和ThreadLocalHoldCounter类实现的。其中:
- HoldCounter类:次要是定义了一个计数器count和一个线程编号tid变量,其中计数器count默认值为0,而线程编号tid通过_getThreadId_(Thread._currentThread_())办法来获取。
- ThreadLocalHoldCounter类:基于ThreadLocal和HoldCounter来提供了initialValue()办法,次要是实例话化HoldCounter类。
共用状态常量:次要是在外部的同步器中Sync类中定义了相干常量,其中:
- SHARED_SHIFT: 次要用于标记位移的位数,默认采纳 整型16位
- SHARED_UNIT:示意读锁加锁操作时每次对应的状态值大小,将1左挪动16位正好对应高16位的1.
- MAX_COUNT:示意读锁能执行加锁操作的最大次数,个别为16个二进制的1
- EXCLUSIVE_MASK:写锁的掩码,个别为16个二进制的1
次要办法:次要提供了统计读写锁状态值的sharedCount()办法和exclusiveCount()办法,其中:
- sharedCount()办法:获取读锁的状态码值,依据指标参数(targetParam)左移16位即可失去
- exclusiveCount()办法:获取写锁的状态码值,依据指标参数(targetParam)同写锁的掩码做逻辑与(&)运算便可失去。
一般来说,AQS根底同步器的共享状态变量是整型的32位,要基于一个AQS根底同步器实现读写锁的共享一个共享变量。
其中,最偏心的形式设计形式就是读锁与写锁各自占用16位,就意味着读锁占用的是高16位,写锁占用的是低16位的。
然而,在获取读写锁的状态值的时候,还会波及一些额定的计算,这样的设计形式可能会须要用到位移和逻辑与操作等。
2.3 基于Sync抽象类封装FairSync偏心同步器
/** ReentrantReadWriteLock锁-基于Sync抽象类封装FairSync偏心同步器 */static final class FairSync extends Sync { private static final long serialVersionUID = -2274990926593161451L; /** ReentrantReadWriteLock锁- 实现writerShouldBlock办法*/ final boolean writerShouldBlock() { return hasQueuedPredecessors(); } /** ReentrantReadWriteLock锁- 实现readerShouldBlock办法*/ final boolean readerShouldBlock() { return hasQueuedPredecessors(); }}
- 实现形式:基于Sync抽象类封装FairSync偏心同步器,示意反对偏心模式
次要办法:次要实现实现writerShouldBlock()办法和readerShouldBlock()办法,其中:
- writerShouldBlock()办法:通过hasQueuedPredecessors()实现
- readerShouldBlock()办法:通过apparentlyFirstQueuedIsExclusive()实现
2.4 基于Sync抽象类封装NonfairSync非偏心同步器
/** ReentrantReadWriteLock锁-基于Sync抽象类封装FairSync偏心同步器 */static final class NonfairSync extends Sync { private static final long serialVersionUID = -8159625535654395037L; /** ReentrantReadWriteLock锁- 实现writerShouldBlock办法*/ final boolean writerShouldBlock() { return false; // writers can always barge } /** ReentrantReadWriteLock锁- 实现readerShouldBlock办法*/ final boolean readerShouldBlock() { return apparentlyFirstQueuedIsExclusive(); }}
- 实现形式:基于Sync抽象类封装NonfairSync非偏心同步器,示意反对非偏心模式
次要办法:次要实现实现writerShouldBlock()办法和readerShouldBlock()办法,其中:
- writerShouldBlock()办法:默认返回false
- readerShouldBlock()办法:通过apparentlyFirstQueuedIsExclusive()实现
2.5 基于Lock接口实现ReadLock读锁外部类
/** ReentrantReadWriteLock锁-基于Lock接口实现ReadLock读锁外部类*/public static class ReadLock implements Lock, java.io.Serializable { private static final long serialVersionUID = -5992448646407690164L; /** ReentrantReadWriteLock锁-ReadLock读锁外部类-同步器 */ private final Sync sync; /** ReentrantReadWriteLock锁-ReadLock读锁外部类-外部构造方法*/ protected ReadLock(ReentrantReadWriteLock lock) { sync = lock.sync; } /** ReentrantReadWriteLock锁-ReadLock读锁外部类-获取锁办法(默认共享模式)*/ public void lock() { sync.acquireShared(1); } /** ReentrantReadWriteLock锁-ReadLock读锁外部类-获取锁办法(反对中断机制)*/ public void lockInterruptibly() throws InterruptedException { sync.acquireSharedInterruptibly(1); } /** ReentrantReadWriteLock锁-ReadLock读锁外部类-尝试获取锁(个别模式)*/ public boolean tryLock() { return sync.tryReadLock(); } /** ReentrantReadWriteLock锁-ReadLock读锁外部类-尝试获取锁(反对超时机制)*/ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireSharedNanos(1, unit.toNanos(timeout)); } /** ReentrantReadWriteLock锁-ReadLock读锁外部类-开释锁*/ public void unlock() { sync.releaseShared(1); } /** ReentrantReadWriteLock锁-ReadLock读锁外部类-条件变量*/ public Condition newCondition() { throw new UnsupportedOperationException(); } public String toString() { int r = sync.getReadLockCount(); return super.toString() + "[Read locks = " + r + "]"; }}
- 实现形式:次要是基于Lock接口来实现的ReadLock锁,同时通过构造方法指定了一个外部同步器Sync,其对应的办法都是基于AQS根底同步器的共享模式来实现的。
获取锁形式:次要提供了4个办法来实现锁的获取,其中:
- 无参数的lock()办法: 获取锁的个别模式,次要是基于AQS根底同步器中的acquireShared(int arg)办法来实现,其外围解决逻辑是doAcquireShared(int arg)办法
- 无参数的lockInterruptibly()办法:获取可中断锁的模式,次要是基于AQS根底同步器中的acquireSharedInterruptibly(int arg)办法来实现,其外围解决逻辑是doAcquireSharedInterruptibly(int arg)办法
- 无参数的tryLock()办法:尝试获取ReadLock锁,次要是基于AQS根底同步器中的tryReadLock()办法来实现,其外围解决逻辑是自旋+compareAndSetState()办法的加持CAS操作的。
- 有参数的ryLock()办法:尝试获取ReadLock锁,反对超时机制,次要是基于AQS根底同步器中的tryAcquireSharedNanos(int arg, long nanosTimeout)办法来实现,其外围解决逻辑是在doAcquireSharedNanos(int arg, long nanosTimeout)办法,次要是自旋+shouldParkAfterFailedAcquire()办法的加持CAS操作的。
- 开释锁形式:次要提供了一个unlock()办法来实现ReadLock 的开释,其中实质是基于AQS根底同步器中的releaseShared(int arg) 办法,其中外围解决逻辑是doReleaseShared()的办法,其外围解决是自旋+compareAndSetWaitStatus()办法来加持CAS操作的。
2.6 基于Lock接口实现WriteLock写锁外部类
/** ReentrantReadWriteLock锁-基于Lock接口实现WriteLock写锁外部类*/public static class WriteLock implements Lock, java.io.Serializable { private static final long serialVersionUID = -4992448646407690164L; /** ReentrantReadWriteLock锁-WriteLock写锁外部类-同步器*/ private final Sync sync; /** ReentrantReadWriteLock锁-WriteLock写锁外部类-外部构造方法*/ protected WriteLock(ReentrantReadWriteLock lock) { sync = lock.sync; } /** ReentrantReadWriteLock锁-WriteLock写锁外部类-获取锁办法(独占模式)*/ public void lock() { sync.acquire(1); } /** ReentrantReadWriteLock锁-WriteLock写锁外部类-获取锁办法(可中断)*/ public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } /** ReentrantReadWriteLock锁-WriteLock写锁外部类-获取锁办法(个别模式)*/ public boolean tryLock( ) { return sync.tryWriteLock(); } /** ReentrantReadWriteLock锁-WriteLock写锁外部类-获取锁办法(反对超时机制)*/ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } /** ReentrantReadWriteLock锁-WriteLock写锁外部类-开释锁*/ public void unlock() { sync.release(1); } /** ReentrantReadWriteLock锁-WriteLock写锁外部类-条件变量*/ public Condition newCondition() { return sync.newCondition(); } public String toString() { Thread o = sync.getOwner(); return super.toString() + ((o == null) ? "[Unlocked]" : "[Locked by thread " + o.getName() + "]"); } /** ReentrantReadWriteLock锁-WriteLock写锁外部类-是否独占判断*/ public boolean isHeldByCurrentThread() { return sync.isHeldExclusively(); } /** ReentrantReadWriteLock锁-WriteLock写锁外部类-统计数量*/ public int getHoldCount() { return sync.getWriteHoldCount(); }}
- 实现形式:次要是基于Lock接口来实现的WriteLock锁,同时通过构造方法指定了一个外部同步器Sync,其对应的办法都是基于AQS根底同步器的独占模式来实现的。
获取锁式:次要提供了4个办法来实现锁的获取,其中:
- 无参数的lock()办法: 获取WriteLock锁的个别模式,次要是基于AQS根底同步器中的acquire(int arg)办法来实现,其外围解决逻辑是acquireQueued(final Node node, int arg)办法
- 无参数的lockInterruptibly()办法:获取WriteLock锁可中断锁的模式,次要是基于AQS根底同步器中的acquireInterruptibly(int arg)办法来实现,其外围解决逻辑是doAcquireInterruptibly(int arg)办法
- 无参数的tryLock()办法:尝试获取WriteLock锁,次要是基于AQS根底同步器中的tryReadLock()办法来实现,其外围解决逻辑是自旋+compareAndSetState()办法的加持CAS操作的。
- 有参数的ryLock()办法:尝试获取WriteLock锁,反对超时机制,次要是基于AQS根底同步器中的tryAcquireNanos(int arg, long nanosTimeout)办法来实现,其外围解决逻辑是在doAcquireNanos(int arg, long nanosTimeout)办法,次要是自旋+shouldParkAfterFailedAcquire()办法的加持CAS操作的。
- 开释锁形式:次要提供了一个unlock()办法来实现ReadLock 的开释,其中实质是基于AQS根底同步器中unparkSuccessor(Node node)办法,次要是通过_compareAndSetWaitStatus_()办法来加持CAS操作的。
3. 具体实现
public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable { private static final long serialVersionUID = -6992448646407690164L; /** ReentrantReadWriteLock锁-外部ReadLock类 */ private final ReentrantReadWriteLock.ReadLock readerLock; /** ReentrantReadWriteLock锁-外部WriteLock类 */ private final ReentrantReadWriteLock.WriteLock writerLock; /** ReentrantReadWriteLock锁-外部同步器 */ final Sync sync; /** ReentrantReadWriteLock锁-实例化Unsafe反对 */ private static final sun.misc.Unsafe UNSAFE; /** ReentrantReadWriteLock锁-线程偏移量 */ private static final long TID_OFFSET; /** ReentrantReadWriteLock锁-基于AQS封装外部同步器 */ abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = 6317671515068378041L; static final int SHARED_SHIFT = 16; static final int SHARED_UNIT = (1 << SHARED_SHIFT); static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1; static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1; private transient ThreadLocalHoldCounter readHolds; private transient HoldCounter cachedHoldCounter; private transient Thread firstReader = null; private transient int firstReaderHoldCount; Sync() { readHolds = new ThreadLocalHoldCounter(); setState(getState()); // ensures visibility of readHolds } abstract boolean readerShouldBlock(); abstract boolean writerShouldBlock(); //... 其余代码 } /** ReentrantReadWriteLock锁-无参数结构(默认非偏心模式) */ public ReentrantReadWriteLock() { this(false); } /** ReentrantReadWriteLock锁-有参数结构(可选偏心/非偏心模式) */ public ReentrantReadWriteLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); readerLock = new ReadLock(this); writerLock = new WriteLock(this); } /** ReentrantReadWriteLock锁-获取写锁 */ public ReentrantReadWriteLock.WriteLock writeLock() { return writerLock; } /** ReentrantReadWriteLock锁-获取读锁 */ public ReentrantReadWriteLock.ReadLock readLock() { return readerLock; } /** ReentrantReadWriteLock锁-获取线程变量 */ public final boolean isFair() { return sync instanceof FairSync; } /** ReentrantReadWriteLock锁-获取线程变量 */ protected Thread getOwner() { return sync.getOwner(); } /** ReentrantReadWriteLock锁-获取线程变量 */ public int getReadLockCount() { return sync.getReadLockCount(); } /** ReentrantReadWriteLock锁-获取线程变量 */ public boolean isWriteLocked() { return sync.isWriteLocked(); } /** ReentrantReadWriteLock锁-获取线程变量 */ public boolean isWriteLockedByCurrentThread() { return sync.isHeldExclusively(); } /** ReentrantReadWriteLock锁-获取线程变量 */ public int getWriteHoldCount() { return sync.getWriteHoldCount(); } /** ReentrantReadWriteLock锁-获取线程变量 */ public int getReadHoldCount() { return sync.getReadHoldCount(); } /** ReentrantReadWriteLock锁-获取线程变量 */ protected Collection<Thread> getQueuedWriterThreads() { return sync.getExclusiveQueuedThreads(); } /** ReentrantReadWriteLock锁-获取线程变量 */ protected Collection<Thread> getQueuedReaderThreads() { return sync.getSharedQueuedThreads(); } /** ReentrantReadWriteLock锁-获取线程变量 */ public final boolean hasQueuedThreads() { return sync.hasQueuedThreads(); } /** ReentrantReadWriteLock锁-获取线程变量 */ public final boolean hasQueuedThread(Thread thread) { return sync.isQueued(thread); } /** ReentrantReadWriteLock锁-获取线程变量 */ public final int getQueueLength() { return sync.getQueueLength(); } /** ReentrantReadWriteLock锁-获取线程变量 */ protected Collection<Thread> getQueuedThreads() { return sync.getQueuedThreads(); } /** ReentrantReadWriteLock锁-获取线程变量 */ public boolean hasWaiters(Condition condition) { if (condition == null) throw new NullPointerException(); if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) throw new IllegalArgumentException("not owner"); return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition); } /** ReentrantReadWriteLock锁-获取线程变量 */ protected Collection<Thread> getWaitingThreads(Condition condition) { if (condition == null) throw new NullPointerException(); if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) throw new IllegalArgumentException("not owner"); return sync.getWaitingThreads((AbstractQueuedSynchronizer.ConditionObject)condition); } /** ReentrantReadWriteLock锁-获取线程变量 */ public int getWaitQueueLength(Condition condition) { if (condition == null) throw new NullPointerException(); if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) throw new IllegalArgumentException("not owner"); return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition); } /** ReentrantReadWriteLock锁-获取线程变量 */ static final long getThreadId(Thread thread) { return UNSAFE.getLongVolatile(thread, TID_OFFSET); } /** ReentrantReadWriteLock锁-反射机制实例化Unsafe */ static { try { UNSAFE = sun.misc.Unsafe.getUnsafe(); Class<?> tk = Thread.class; TID_OFFSET = UNSAFE.objectFieldOffset (tk.getDeclaredField("tid")); } catch (Exception e) { throw new Error(e); } } }
读写锁同步器:次要提供了2个构造方法来实现读写锁的治理,其中:
- 无参数构造方法:默认非偏心模式,次要是通过this关键字来指定的
- 有参数构造方法:可选偏心/非偏心模式,根据指定传入偏心标记fair来实例化NonfairSync非偏心同步器和FairSync偏心同步器,其中,当fair=true时,是偏心平模式;否则,当fair=false时为非偏心模式。同时,实例化ReadLock和WriteLock对象。
读锁次要办法:对于读锁的操作,个别咱们只须要关注readLock()办法和相似getReadXX() 办法,其中:
- readLock()办法:次要用于获取和实现读锁ReadLock
- getReadHoldCount() 办法:次要用于统计某个线程对于读锁的持有状况
- getReadLockCount() 办法:次要用于统计某个线程对于读锁的获取的次数
写锁次要办法:对于读锁的操作,个别咱们只须要关注readLock()办法和相似蕴含xWriteXX() 办法,其中:
- writeLock() 办法:次要用于获取和实现写锁WriteLock
- getWriteHoldCount()办法:次要用于统计以后线程对于写锁WriteLock的持有状况
- isWriteLocked()办法:次要用于判断某个线程对于写锁WriteLock的是否加锁
- isWriteLockedByCurrentThread() 办法:次要用于判断以后线程对于写锁WriteLock的是否加锁
条件队列操作方法:还提供了一系列的对于条件变量队列操作方法,其中:
- getQueuedWriterThreads() 办法:次要用于获取线程期待获取写锁WriteLock的状况
- getQueuedReaderThreads() 办法:次要用于获取线程期待获取读锁ReadLock的状况
- getQueuedThreads()办法:次要用于获取线程期待获取读锁ReadLock和写锁WriteLock的状况
- getQueueLength() 办法:次要用于获取线程期待获取读锁ReadLock和写锁WriteLock的个数
期待队列操作方法: 还提供了一系列的对于期待队列操作方法,其中:
- getWaitingThreads() 办法:次要根据Condition来用于获取期待队列中所有的线程的对象
- getWaitQueueLength() 办法:次要根据Condition来用于获取期待队列中所有的线程对于写锁WriteLock的相干的个数
其余办法:除此之外,还提供了一些队列操作的惯例办法,其中:
- hasQueuedThread() 办法:次要根据单个Thread对象用于获取线程是否有获取读锁ReadLock和写锁WriteLock的状况
- hasQueuedThreads() 办法:次要用于获取多个线程是否有获取读锁ReadLock和写锁WriteLock的状况
- hasWaiters()办法:次要根据Condition来用于判断期待队列中所有的线程对于写锁WriteLock的相干状况
- isFair() 办法:用于判断是否偏心模式
- getThreadId()办法:获取线程编号ID,次要是通过指定_UNSAFE_.getLongVolatile(thread, _TID_OFFSET_)实现。
综上所述,ReentrantReadWriteLock锁是基于AQS根底同步器的共享模式和独享模式独特孵化的产物,反对偏心/非偏心模式,其中的ReadLock和WriteLock是基于同一个AQS根底同步器来实现,保护了共用状态变量机制。
写在最初
通过对Java畛域中,JDK外部提供的各种锁的实现来看,始终围绕的外围次要还是基于AQS根底同步器来实现的,然而AQS根底同步器不是一种非它不可的技术标准规范,更多的只是一套技术参考指南。
然而,实际上,Java对于锁的实现与使用远远不止这些,还有相位器(Phaser)和交换器(Exchanger),以及在Java JDK1.8版本之前并发容器ConcurrentHashMap中应用的分段锁(Segment)。
不论是何种实现和利用,在Java并发编程畛域来讲,都是围绕线程平安问题的角度去思考的,只是针对于各种各样的业务场景做的具体的实现。
肯定意义上来讲,对线程加锁只是并发编程的实现形式之一,绝对于理论利用来说,Java畛域中的锁都只是一种繁多利用的锁,只是给咱们把握Java并发编程提供一种思维没,喋喋不休也不可能详尽。
到此为止,这算是对于Java畛域中并发锁的最终章,文中表述均为集体认识和集体了解,如有不到之处,忘请谅解也请给予批评指正。
最初,技术钻研之路任重而道远,愿咱们熬的每一个通宵,都撑得起咱们想在这条路上走上来的勇气,将来依然可期,与各位程序编程君共勉!