ReentrantLock
ReentrantLock分为公平锁和非公平锁,从有参构造器中可以看出,公平锁对象创建是内部类:new NonfairSync()
。
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
NonfairSync
的源码如下所示,先分析lock()
方法,从该方法可以看出,所谓的上锁过程,就是将AQS中的变量status设置为1,修改成功,便将锁的持有者设为本线程。
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
如果获取失败,则会调用父类AQS中的acquire(1)
方法尝试获取锁,NonfairSync中重写了acquire(int arg)
中的tryAcquire(arg)
方法,通过nonfairTryAcquire(acquires)
方法来获取锁:
这个方法里,当前线程会尝试获取锁,分为三种情况:第一种,当前锁未被其它线程持有,当前线程进行第一次锁竞争;第二种,当前锁已被占用,判断持锁线程是不是自己,如果是,则直接修改锁状态(加1),这便是可重入锁;如果前两种都不满足,那么获取锁失败,返回false,进入AQS的CLH锁队列中等待被唤醒。
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState(); //获取AQS中的状态值
//state为0,表示此时没有线程持有锁,当前线程可以去尝试获取锁
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//如果state不为0,此时判断持锁线程是不是当前线程,因为ReentrantLock是可重入锁,如果是当前线程,state加1
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
//小于0,表示锁重入数超出了int范围,
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
//这里不用CAS,是因为同一个线程修改state,无安全问题
setState(nextc);
return true;
}
return false;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。