juc包中,aqs实现的公平锁和非公平锁的最主要的区别是:非公平锁中,那些尝试获取锁且尚未进入等待队列的线程会和等待队列head结点的线程发生竞争。公平锁中,在获取锁时,增加了isFirst(current)判断,当且仅当,等待队列为空或当前线程是等待队列的头结点时,才可尝试获取锁。
1.1 NonfairSync.lock()
final void lock() {
if (compareAndSetState(0, 1))//没有进入等待队列,也可以获取锁
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
2.1 FairSync.lock()
final void lock() {
acquire(1);
}
2.2 FairSync.tryAcquire()
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (isFirst(current) &&//只有等待队列为空或当前线程是队列头结点才可以获取锁
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;
}
关于当前线程是否是队列头结点的判断,详见下面两个函数:
2.3 AbstractQueuedSynchronizer.isFirst()
/**
* Return {@code true} if the queue is empty or if the given thread
* is at the head of the queue. This is reliable only if
* <tt>current</tt> is actually Thread.currentThread() of caller.
*/
final boolean isFirst(Thread current) {
Node h, s;
return ((h = head) == null ||
((s = h.next) != null && s.thread == current) ||
fullIsFirst(current));
}
2.4 AbstractQueuedSynchronizer.fullIsFirst()
final boolean fullIsFirst(Thread current) {
// same idea as fullGetFirstQueuedThread
Node h, s;
Thread firstThread = null;
if (((h = head) != null && (s = h.next) != null &&
s.prev == head && (firstThread = s.thread) != null))
return firstThread == current;
Node t = tail;
while (t != null && t != head) {
Thread tt = t.thread;
if (tt != null)
firstThread = tt;
t = t.prev;
}
return firstThread == current || firstThread == null;
}
总结:
线程为首结点成立的情况:
1.等待队列为空。
2.等待队列head的next结点的thread为当前线程(head.next.thread = currentThread),即线程为等待队列除哑结点外的第一个结点。
3.等待队列head结点到某个结点(暂命名为结点s),之间的所有结点的thread变量为null,且结点s的thread为当前线程。