概述
- 基于AQS(AbstractQueuedSynchronizer,concurrent包中的一个抽象类)
- AQS基于CAS(Compare and Swap,一种并发技术),CAS在java中靠Unsafe实现(native,依靠C++和汇编)
- Unsafe
- Access restriction: The type 'Unsafe' is not API (restriction on required library 'C:\Program Files\Java\jdk1.8.0_111\jre\lib\rt.jar')
- 已测试,确实跑不动
- @CallerSensitive,被注解的方法,需要方法调用者具备一定权限
- bootstrap class loader加载的类可调用
- extension class loader加载的类可调用
private final Sync sync; // 持有Sync,锁的功能来自于Sync
private volatile int state; // Sync中属性
// 默认非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
// 实际调用sync的方法,Sync是个抽象类,实现类有FairSync和NonfairSync,默认非公平
lock.lock()
sync.lock()
// NonfairSync实现
NonfairSync
final void lock() {
if (compareAndSetState(0, 1)) // 试着抢一把(这就是非公平的特点)
setExclusiveOwnerThread(Thread.currentThread()); // 设置当前线程独占锁
else
acquire(1); // 抢夺不成,排队去(公平锁直接来这)
}
源码解析 - lock()
thread-003.jpg
第1个线程
- compareAndSetState检查当前lock的state属性
- 采用unsafe.compareAndSwapInt(this, stateOffset, expect, update)
- 检查this对象的偏移地址为stateOffset的属性
- stateOffset:unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("state"))
- 是否与expect一致
- 若是一致,就更新为update
- 意味着,原state值为0才表示这个lock没有被别人持有,当前线程才可以改值
- 检查this对象的偏移地址为stateOffset的属性
- NonfairSync持有一个从AbstractOwnableSynchronizer继承过来的exclusiveOwnerThread属性,表示独占锁线程
- 第一个获取锁的线程做了两件事情
- 设置AQS(即Sync)的state为1
- 设置exclusiveOwnerThread为当前线程
第2个线程
-
线程2也尝试获取同一个锁,在线程1没有释放锁的情况下必然是行不通的,所以线程2就要阻塞
-
那么,线程2如何被阻塞