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将当前线程加入队尾 }