1、在公平实现中,sync为FairSync,其lock()方法与NonfairSync相比,少了抢占的步骤:
- NonfairSync中的lock():
final void lock() {
if (compareAndSetState(0, 1))//抢占
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
}
- FairSync中的lock():
final void lock() {
acquire(1);
}
2、在各自重写AQS的tryAcquire()方法中,NonfairSync调用的是nonfairTryAcquire(),FairSync调用的是tryAquire()。他们的区别是,当锁状态为为0的时候,非公平使用非公平锁的线程会直接尝试获取锁,二使用公平锁的线程则先会判断是否有线程在排队。
- 非公平:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {//直接尝试获取锁
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
- 公平:
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
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;
}
}
hasQueuedPredecessors():
public final boolean hasQueuedPredecessors() {
Node t = tail;
Node h = head;
Node s;
return h != t && // 队列中的队首和队尾元素不相同。如果相同,直接返回假,表明没有节点在排队,外部取非为真,则可以尝试获取锁。
((s = h.next) == null || s.thread != Thread.currentThread()); //如果头尾不一样:如果头尾队列中的第二个元素不为null,且第二个元素中的线程是当前线程才返回false,方法返回false外部取非为真,才能尝试获取锁。这里如果返回true,说明队列中至少存在tail、head两个节点,就会执行acquireQueued将当前线程加入队尾
}