JUC–ReetrantLock原理及源码分析(一)之相关概念
ReentrantLock的依赖/继承关系图
相关概念:
互斥锁(排它锁)/共享锁
互斥锁:同一把锁只能一个线程持有。
共享锁:同一把锁可多个线程同时持有。
重入锁
线程中a方法调用b方法,因为是同一把锁,可直接获取, lock一次参数state + 1
public void a() {
lock.lock();
b();
lock.unlock();
}
public void b() {
lock.lock();
...
lock.unlock();
}
AQS
AbstractQueuedSynchronizer
阻塞队列
AbstractQueuedSynchronizer#Node -> AQS维护的一个双向队列
公平锁/非公平锁
通过ReentrantLock构造函数分析得出,默认为非公平锁。
有参构造传递true则为公平锁。
区别:
- 公平锁:并发环境中,线程直接进入等待队列。
- 非公平锁:并发环境中,线程首先获取锁,获取不到再进入等待队列。
出现临界点 -> 插队现象 :5个线程抢占锁,四个线程会等待,这时1线程执行完,刚刚释放锁,6线程进来了,插队抢占锁。
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
interrupt 传递
// 外部调用线程的interrupted方法 休眠中的线程可以感知并且继续抢占锁,同时将interrupted参数向上传递
Thread.interrupted();
// 这个场景中会有用 假设interrupted不能够上传,这段代码永远不会结束
new Thread(new Runnable() {
@Override
public void run() {
lock.lock();
while (!Thread.currentThread().isInterrupted()) {
}
lock.unlock();
}
}).start();
CAS(Compare And Swap)比较和交换
- 可见性 volatile
- 原子性 cas()操作
- 有序性 缓存锁(MESI),总线锁