本章主要是介绍了如何使用Lock接口、队列同步器、重入锁、读写锁、Condition接口来实现锁以及LockSupport工具。
Lock接口
Java SE 5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显式地获取和释放锁。
1 | Lock lock = new ReentrantLock(); |
队列同步器
队列同步器AbstractQueuedSynchronizer(以下简称同步器),是用来构建锁或者其他同步组件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作,并发包的作者(Doug Lea)期望它能够成为实现大部分同步需求的基础。
三个关键方法:
- getState():获取当前同步状态。
- setState(int newState):设置当前同步状态。
- compareAndSetState(int expect,int update):使用CAS设置当前状态,该方法能够保证状态设置的原子性。
1 | class Mutex implements Lock { |
重入锁
重入锁ReentrantLock,顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁。
实现重进入需要解决两个问题:
- 线程再次获取锁
- 锁的最终释放
1 | final boolean nonfairTryAcquire(int acquires) { |
读写锁(ReentrantReadWriteLock)
ReadWriteLock仅定义了获取读锁和写锁的两个方法,即readLock()方法和writeLock()方法,而ReentrantReadWriteLock就其实现类。
1 | public class Cache { |
Condition接口
任意一个Java对象,都拥有一组监视器方法(定义在java.lang.Object上),主要包括wait()、wait(long timeout)、notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,但是这两者在使用方式以及功能特性上还是有差别的。
1 | Lock lock = new ReentrantLock(); |
LockSupport工具
LockSupport定义了一组的公共静态方法,是构建同步组件的基础工具。