本章,咱们介绍锁的架构;后面的章节将会对它们逐个进行分析介绍。目录以下:程序员
- 01. Java多线程系列--“JUC锁”01之 框架
- 02. Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock
- 06. Java多线程系列--“JUC锁”03之 Condition条件
- 07. Java多线程系列--“JUC锁”04之 LockSupport
- 03. Java多线程系列--“JUC锁”05之 公平锁(上)
- 04. Java多线程系列--“JUC锁”06之 公平锁(下)
- 05. Java多线程系列--“JUC锁”07之 非公平锁
- 08. Java多线程系列--“JUC锁”08之 共享锁和ReentrantReadWriteLock (待更新)
- 09. Java多线程系列--“JUC锁”09之 CountDownLatch原理和示例(待更新)
- 10. Java多线程系列--“JUC锁”10之 CyclicBarrier原理和示例(待更新)
- 11. Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例(待更新)
根据锁的添加到Java中的时间,Java中的锁,能够分为"同步锁"和"JUC包中的锁"。多线程
同步锁
即经过synchronized关键字来进行同步,实现对竞争资源的互斥访问的锁。Java 1.0版本中就已经支持同步锁了。架构
同步锁的原理是,对于每个对象,有且仅有一个同步锁;不一样的线程能共同访问该同步锁。可是,在同一个时间点,该同步锁能且只能被一个线程获取到。这样,获取到同步锁的线程就能进行CPU调度,从而在CPU上执行;而没有获取到同步锁的线程,必须进行等待,直到获取到同步锁以后才能继续运行。这就是,多线程经过同步锁进行同步的原理!框架
JUC包中的锁
相比同步锁,JUC包中的锁的功能更增强大,它为锁提供了一个框架,该框架容许更灵活地使用锁,只是它的用法更难罢了。ui
JUC包中的锁,包括:Lock接口,ReadWriteLock接口,LockSupport阻塞原语,Condition条件,AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer三个抽象类,ReentrantLock独占锁,ReentrantReadWriteLock读写锁。因为CountDownLatch,CyclicBarrier和Semaphore也是经过AQS来实现的;所以,我也将它们概括到锁的框架中进行介绍。spa
先看看锁的框架图,以下所示。线程
01. Lock接口对象
JUC包中的 Lock 接口支持那些语义不一样(重入、公平等)的锁规则。所谓语义不一样,是指锁但是有"公平机制的锁"、"非公平机制的锁"、"可重入的锁"等等。"公平机制"是指"不一样线程获取锁的机制是公平的",而"非公平机制"则是指"不一样线程获取锁的机制是非公平的","可重入的锁"是指同一个锁可以被一个线程屡次获取。blog
02. ReadWriteLock继承
ReadWriteLock 接口以和Lock相似的方式定义了一些读取者能够共享而写入者独占的锁。JUC包只有一个类实现了该接口,即 ReentrantReadWriteLock,由于它适用于大部分的标准用法上下文。但程序员能够建立本身的、适用于非标准要求的实现。
03. AbstractOwnableSynchronizer/AbstractQueuedSynchronizer/AbstractQueuedLongSynchronizer
AbstractQueuedSynchronizer就是被称之为AQS的类,它是一个很是有用的超类,可用来定义锁以及依赖于排队阻塞线程的其余同步器;ReentrantLock,ReentrantReadWriteLock,CountDownLatch,CyclicBarrier和Semaphore等这些类都是基于AQS类实现的。AbstractQueuedLongSynchronizer 类提供相同的功能但扩展了对同步状态的 64 位的支持。二者都扩展了类 AbstractOwnableSynchronizer(一个帮助记录当前保持独占同步的线程的简单类)。
04. LockSupport
LockSupport提供“建立锁”和“其余同步类的基本线程阻塞原语”。
LockSupport的功能和"Thread中的Thread.suspend()和Thread.resume()有点相似",LockSupport中的park() 和 unpark() 的做用分别是阻塞线程和解除阻塞线程。可是park()和unpark()不会遇到“Thread.suspend 和 Thread.resume所可能引起的死锁”问题。
05. Condition
Condition须要和Lock联合使用,它的做用是代替Object监视器方法,能够经过await(),signal()来休眠/唤醒线程。
Condition 接口描述了可能会与锁有关联的条件变量。这些变量在用法上与使用 Object.wait 访问的隐式监视器相似,但提供了更强大的功能。须要特别指出的是,单个 Lock 可能与多个 Condition 对象关联。为了不兼容性问题,Condition 方法的名称与对应的 Object 版本中的不一样。
06. ReentrantLock
ReentrantLock是独占锁。所谓独占锁,是指只能被独自占领,即同一个时间点只能被一个线程锁获取到的锁。ReentrantLock锁包括"公平的ReentrantLock"和"非公平的ReentrantLock"。"公平的ReentrantLock"是指"不一样线程获取锁的机制是公平的",而"非公平的 ReentrantLock"则是指"不一样线程获取锁的机制是非公平的",ReentrantLock是"可重入的锁"。
ReentrantLock的UML类图以下:
(01) ReentrantLock实现了Lock接口。
(02) ReentrantLock中有一个成员变量sync,sync是Sync类型;Sync是一个抽象类,并且它继承于AQS。
(03) ReentrantLock中有"公平锁类"FairSync和"非公平锁类"NonfairSync,它们都是Sync的子类。ReentrantLock中sync对象,是FairSync与NonfairSync中的一种,这也意味着ReentrantLock是"公平锁"或"非公平锁"中的一种,ReentrantLock默认是非公平锁。
07. ReentrantReadWriteLock
ReentrantReadWriteLock是读写锁接口ReadWriteLock的实现类,它包括子类ReadLock和WriteLock。ReentrantLock是一种独占锁,而WriteLock是共享锁。
ReentrantReadWriteLock的UML类图以下:
(01) ReentrantReadWriteLock实现了ReadWriteLock接口。
(02) ReentrantReadWriteLock中包含sync对象,读锁readerLock和写锁writerLock。读锁ReadLock和写锁WriteLock都实现了Lock接口。
(03) 和"ReentrantLock"同样,sync是Sync类型;并且,Sync也是一个继承于AQS的抽象类。Sync也包括"公平锁"FairSync和"非公平锁"NonfairSync。
08. CountDownLatch
CountDownLatch是一个同步辅助类,在完成一组正在其余线程中执行的操做以前,它容许一个或多个线程一直等待。
CountDownLatch的UML类图以下:
CountDownLatch包含了sync对象,sync是Sync类型。CountDownLatch的Sync是实例类,它继承于AQS。
09. CyclicBarrier
CyclicBarrier是一个同步辅助类,容许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。由于该 barrier 在释放等待线程后能够重用,因此称它为循环 的 barrier。
CyclicBarrier的UML类图以下:
CyclicBarrier是包含了"ReentrantLock对象lock"和"Condition对象trip",它是经过独占锁实现的。
CyclicBarrier和CountDownLatch的区别是:
(01) CountDownLatch的做用是容许1或N个线程等待其余线程完成执行;而CyclicBarrier则是容许N个线程相互等待。
(02) CountDownLatch的计数器没法被重置;CyclicBarrier的计数器能够被重置后使用,所以它被称为是循环的barrier。
10. Semaphore
Semaphore是一个计数信号量,它的本质是一个"共享锁"。
信号量维护了一个信号量许可集。线程能够经过调用acquire()来获取信号量的许可;当信号量中有可用的许可时,线程能获取该许可;不然线程必须等待,直到有可用的许可为止。 线程能够经过release()来释放它所持有的信号量许可。
Semaphore的UML类图以下:
和"ReentrantLock"同样,Semaphore包含了sync对象,sync是Sync类型;并且,Sync也是一个继承于AQS的抽象类。Sync也包括"公平信号量"FairSync和"非公平信号量"NonfairSync。