JDK1.8中ReentrantLock的底层原理解析:
ReentrantLock主要通过CAS+AQS来实现,它支持公平锁和非公平锁,这两者的实现比较类似。
CAS:Compare amd Swap,比较并转换。CAS有3个操作数:内存值V,预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。这个操作是个原子操作,被广泛地应用在Java的底层实现中。在Java中,CAS主要是由sum.misc.Unsafe这个类通过JNI调用CPU底层指令实现。
AQS:就是AbstractQueuedSynchronizer的简称。(不解释 == 不会)
1.初始化方法:
/**
* Creates an instance of {@code ReentrantLock}.
* This is equivalent to using {@code ReentrantLock(false)}.
*/
public ReentrantLock() {
sync = new NonfairSync(); // 默认选择非公平锁
}
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ?
new FairSync() // 公平锁
:
new NonfairSync(); // 非公平锁
}
此处提到了两个内部类:
new FairSync();
new NonfairSync();
他们之间的区别主要在于lock方法:
NonfairSync首先会去尝试获取锁,获取失败之后,会进入队列中进行等待。
FairSync则是先去判断锁是否被其他的线程占有,如果是的话就进入到队列尾部进行等待。
他们都继承了ReenTrantLock.Sync类,ReentrantLock.Sync 类 又继承了 AbstractQueuedSynchronizer
- ReentrantLock.Sync 类 对一些公共方法
- AbstractQueuedSynchronizer 内部维护着一个由双向链表实现的队列 用来记录等待锁释放的线程,
实际操作中 NonfairSync 的使用比较多 这里针对NonfairSync 进行研读
NonfairSync :
/**
* 非公平锁的同步对象
* Sync object for non-fair locks
*/
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}