背景
jdk17也发布很久了,jdk对ReentrantLock做了很多优化,代码简洁了很多,
我这两天简单看了以下,ReentrantLock,发现有可以优化的地方。
类继承结构
整体继承结构没变,还是两个类,NonfairSync 和 FairSync,一个公平锁,一个非公平锁。
再看看方法,方法有改变
NonfairSync的方法
final boolean initialTryLock() {
Thread current = Thread.currentThread();
if (compareAndSetState(0, 1)) { // first attempt is unguarded
setExclusiveOwnerThread(current);
return true;
} else if (getExclusiveOwnerThread() == current) {
int c = getState() + 1;
if (c < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(c);
return true;
} else
return false;
}
tryAcquire
protected final boolean tryAcquire(int acquires) {
if (getState() == 0 && compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
FairSync的类差不多,只是多了判断是否公平判断,可以看到NonfairSync和FairSync 代码类似,
既然使用了模板方法模式,为什么不再优化一下代码,提取方法呢?
将initialTryLock 的 !hasQueuedThreads() 和 !hasQueuedPredecessors()提取到sync里面去,
NonfairSync里面的方法都返回true,FairSync里面再具体判断。
优化建议代码如下
abstract static class Sync extends AbstractQueuedSynchronizer {
protected boolean skipFair() {
throw new UnsupportedOperationException();
}
protected boolean skipCheckQueuedPredecessors() {
throw new UnsupportedOperationException();
}
boolean initialTryLock() {
Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//add skipFair
if (skipFair() && compareAndSetState(0, 1)) {
setExclusiveOwnerThread(current);
return true;
}
} else if (getExclusiveOwnerThread() == current) {
if (++c < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(c);
return true;
}
return false;
}
protected final boolean tryAcquire(int acquires) {
//add skipCheckQueuedPredecessors
if (getState() == 0 && skipCheckQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
}
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
@Override
protected boolean skipFair() {
return true;
}
@Override
protected boolean skipCheckQueuedPredecessors() {
return true;
}
}
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
@Override
protected boolean skipFair() {
return !hasQueuedThreads();
}
@Override
protected boolean skipCheckQueuedPredecessors() {
return !hasQueuedPredecessors();
}
}