主要功能:
-
资源独占以及唤醒
-
同一线程可重复进入
-
公平锁: 如果无锁等待队列, 再尝试获取锁; 非公平锁, 先尝试获取锁,获取不到进入等待队列
实现原理:
利用AQS的的state状态来判断资源是否已锁,同一线程重入加锁,state的状态+1; 同一线程重入解锁,state状态-1(解锁必须为当前独占线程,否则异常); 当state为0时解锁成功。
代码解读:
数据结构
//锁的操作是基于AQS来实现的
private final Sync sync;
//默认非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
//可选公平和非公平锁
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
非公平锁的获取
//abstract static class Sync extends AbstractQueuedSynchronizer
//非公平锁获取
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//直接CAS抢锁
if (compareAndSetState(0, acquires)) {
//抢到锁则把当前线程设置为独占线程
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
//同线程重入, 状态加1
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
//同一线程重入,无线程竞争,无需CAS操作
setState(nextc);
return true;
}
return false;
}
公平锁的获取
//公平锁,锁获取操作
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//线程状态为已解锁,无等待队列再去获取锁
//!hasQueuedPredecessors为与非公平锁的差异点
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
//设置当前独占线程
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
锁释放操作
//abstract static class Sync extends AbstractQueuedSynchronizer
//锁释放
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
//不在同一线程内释放锁,说明出了异常
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
//锁是否成功, 设置独占线程为空
setExclusiveOwnerThread(null);
}
//锁持有计数减1,同线程内无需CAS
setState(c);
return free;
}
网友评论