1. Lock接口
- Lock接口缺少了(通过synchronized块或者方法提供的)隐式获取释放锁的便捷性,但是却拥有了锁获取和释放锁的可操作性,可中断的获取锁以及超时获取锁等多种synchronized关键字所不具备的同步特性
- Lock使用方式代码清单
Lock lock = new ReentranLock();
lock.lock();
try{
}finally{
lock.unlock();
}
- 在finally中释放锁,保证在获取到锁之后,最终能够被释放
- Lock接口提供农耕的synvhronized关键字不具备的主要特性
特性 | 描述 |
---|
尝试非阻塞地获取锁 | 当前线程尝试获取锁,如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁 |
能被中断地获取锁 | 与synchronized不同,获取到锁的线程能够响应中断,当获取到锁的线程被中断时,中断异常将会被抛出,同时锁会被释放 |
超时获取锁 | 在指定的截止时间之前获取锁,如果截止时间到了仍旧无法获取锁,则返回 |
方法名称 | 描述 |
---|
void lock | 获取锁,调用该方法当前线程将会获取锁,当锁获得后,从该方法返回 |
void lockInterruptibly() throws InterruptedException | 可中断的获取锁,和lock()方法不同之处在于该方法会响应中断,即在锁的获取中可以中断当前线程 |
boolean tryLock() | 尝试非阻塞地获取锁,调用该方法后立刻返回,如果能够获取则返回true,反之返回false |
boolean tryLock(long time,TimeUnit unit) throws InterruptedException | 超时获取锁,当前线程在一下3种情况下返回:1). 当前线程在超时时间内获得锁 2). 当前线程在超时时间内中断 3). 超时时间结束,返回false |
void unlock() | 释放锁 |
Condition newCondition() | 获取等待通知组件,该组件和当前的锁绑定,当前线程只有获得了锁,才能调用该组件的wait()方法,而调用后,当前线程将释放锁 |
2. 队列同步器
- 用来构建锁合作和其他同步组件的基础框架,它使用了一个int成员变量表示同步状态,通过内置的FIFO队列来完成资源获取线程的排队工作,期望它成为实现大部分同步需求的基础
2.1 : 队列同步器的接口与示例
- 同步器的设计是基于模板方法模式的,也就是说,使用者需要继承同步器并重写指定的方法,随后将同步器组合在自定义同步组件的实现中,并调用同步器提供的模板方法么人这些模板方法将会调用使用者重写的方法
- 重写方法,需要同步器提供的如下3个方法来访问和修改同步器状态
1). getState() : 获取当前同步状态
2). setState(int newState) : 设置当前同步状态
3). compareAndSetState(int expect,int update) : 使用CAS设置当前状态,该方法能够保证状态设置的原子性 - 同步器可重写方法和描述,如下
方法名称 | 描述 |
---|
protected boolena tryAcquire(int arg) | 独占式获取同步状态,实现该方法需要查询当前状态并判断同步状态是否符合预期,然后进行CAS设置同步状态 |
protected boolean tryRelease(int arg) | 独占式释放同步状态,等待获取同步状态的线程将有机会获取同步状态 |
protected int tryAcquireShared(int arg) | 共享式获取同步状态,返回大于等于0的值,表示获取成功,返回获取失败 |
protected boolean tryReleaseShared(int arg) | 共享式释放同步状态 |
protected boolean isHeldExclusively() | 当前同步器是否在独占模式下呗线程占用,一般该方法表示是否被方便线程独占 |
2.2 : 队列同步器的实现分析
- 同步队列 :
同步器依赖内部的同步队列(FIFO双向队列)来完成同步状态的管理,当前线程获取同步状态失败时,同步器会将当前线程以及等待状态等信息构造成为一个节点(Node)并将其加入同步队列,同时会阻塞当前线程,当同步状态释放时,会把首节点中的线程唤醒,使其再次尝试获取同步状态 - 独占式同步状态获取和释放 :
通过调用同步器的acquire(int arg)方法可以获取同步状态,该方法对中断不敏感,也就是由于线程获取同步状态失败后进入同步队列中,后续对线程进行中断操作时,线程不会从同步队列中移出. - 共享式同步状态获取和释放 :
共享式获取与独占获取最主要的区别在于同一时刻能否有多个线程同时获取到同步状态
共享式访问资源时,其他共享式的访问均被允许,而独占式访问会被阻塞,如果独占式访问资源时,同一时刻其他访问都会被阻塞 - 独占式超时获取同步状态 :
通过调用同步器的doAcquireNanos(int arg,long nanosTimeOut)方法可以超时获取同步状态,即在指定的时间段内获取同步状态,如果获取到返回true,反之,返回false
3.重入锁
- 重入锁ReentranLock,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁,除此之外,该锁还支持获取锁时的公平和非公平性选择
4.读写锁
4.1 : 读写锁的接口与示例
4.2 : 读写锁的实现分析
5.LockSupport工具
6.Condition接口
6.1 : Conidition接口与示例
6.2 : Condition的实现分析
7.本章小结