Lock接口综述
jdk提供了Lock接口,用于复写一些锁相关的逻辑。例如ReentrantLock
与Synchronized相比,Lock提供的功能包括:
尝试非阻塞地获取锁:synchronized一旦获取不到就处于阻塞状态
能被中断地获取锁
超时获取锁
Lock接口提供的方法包括:
void lock()
:获取锁void lockInterruptibly() throws InterruptedException
:可中断地获取锁,意味着获取不到的阻塞流程中,可以感知线程的中断标志位boolean tryLock()
:尝试非阻塞获取锁,调用后立即返回,如果获取到返回true否则返回false,可以增加时间参数,设置获取的超时时间,这时获取不到或超时,都会返回falsevoid unlock()
:释放锁Condition newCondition()
:获取等待通知组件
AQS - 队列同步器 - 锁的基础组件
ReentrantLock、ReentrantReadWriteLock、CountDownLatch等都是基于AQS实现的。Lock面向使用者,AQS面向锁的开发者,它主要是为了简化锁的实现方式,屏蔽锁中的状态管理、等待唤醒等底层操作。
AQS的核心是一个volatile修饰的状态值state和一个volatile修饰的FIFO队列。提供的功能主要包括三大类:
独占式获取和释放锁
void acquire(int)
void acquireInterruptibly(int)
boolean release(int)
共享式获取锁
void acquireShared(int)
void acquireSharedInterruptibly(int)
boolean releaseShared(int)
带时间限制的锁获取
boolean tryAcquireNanos
boolean tryAcquireSharedNanos
AQS源码分析见AQS部分
ReentrantLock
ReentrantLock在共享和独占的基础上,扩展了公平、非公平锁,以及锁可重入概念。具体代码见ReentrantLock部分。
它的核心设计理念是FIFO队列管理公平与非公平竞争
ReentrantReadWriteLock
在ReentrantLock基础上引入了读写分离,通过一个独占锁一个共享锁实现高性能的锁粒度细化。具体代码见ReentrantReadWriteLock部分
它的核心设计理念是通过一个int state做二进制分割,以高低位标识两种锁状态。
LockSupport工具
AQS体系下使用的线程阻塞或唤醒工具,具体分析见LockSupport部分
Condition - 等待/通知机制的实现
对象Object本身是拥有wait()、wait(long)、notify()、notifyAll()这些监视器方法的,配合sychronized锁可以实现等待/通知模式。
Condition是另一种等待通知的实现逻辑,是与Lock配合实现的。它与Object的等待/通知的主要差别有:
等待队列个数:Object监视器公用一个等待队列,Condition是每个对象一个队列
响应中断:Object监视器一定会响应中断,Condition允许不响应中断
等待超时:Object监视器支持超时等待,但不支持指定等待到某个时间点,Condition支持超时等待,也支持指定到某个时间点等待
代码部分见Condition部分
评论区