直接进入lock()方法的tryAcquire方法
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()) { //代表当前有线程持有独占状态,并且不是当前线程。所以当前线程不能持有独占,直接返回false
intnextc = c + acquires;
if(nextc <0)
throw newError("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
-------------------------------------------------------
分析hasQueuedPredecessors方法,
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
Node t =tail;// Read fields in reverse initialization order
Node h =head;
Node s;
return
h != t &&
((s = h.next) ==null|| s.thread!= Thread.currentThread());
}
1、当头结点和尾节点不相等并且 如果head节点的next节点s不为空,并且s不是当前线程。代表头节点执行完后s节点有可能被执行。当前线程无法参与竞争,所以返回true。
2、当头结点和尾节点不相等并且 如果head节点的next节点s不为空,并且s是当前线程。代表头节点执行完后s节点(当前线程)有可能被执行所以返回fasle。(代表上一层可以去竞争独占状态)
3、当头结点和尾节点不相等并且 如果head节点的next节点s为空,那么直接返回true,代表头节点后面没有节点。即当前线程不是头节点的next节点。返回true。不直接参与竞争
4、当头结点和尾节点相等,返回false,代表这个节点执行完之后没有节点在同步队列,当前线程可以直接参与竞争
以上四点保证了如果有其他的线程在头节点的next上等待并且head节点的next节点不是当前节点时,那么这个线程不能直接参与竞争,只能通过后面的循环cas方法去获取独占状态。在非公平锁中,当当前线程去获取state是0时,当前线程可以直接通过cas方法去尝试获取状态,一旦成功,那么如果在头节点后面原本有符合条件的等待执行的线程A,就无法获取独占状态,因此,此时对于A就是不公平的。
其它的逻辑都和非公平锁一样。