ReentrantLock中有两种Sync,一种是NonfairSync另一种是FairSync。它两同时继承Sync类。可以在创建ReentrantLock的时候指定用那种锁。
在FairSync的lock方法中,会调用acquire(1),而acquire方法如下
/**
* Acquires in exclusive mode, ignoring interrupts. Implemented
* by invoking at least once {@link #tryAcquire},
* returning on success. Otherwise the thread is queued, possibly
* repeatedly blocking and unblocking, invoking {@link
* #tryAcquire} until success. This method can be used
* to implement method {@link Lock#lock}.
*
* @param arg the acquire argument. This value is conveyed to
* {@link #tryAcquire} but is otherwise uninterpreted and
* can represent anything you like.
*/
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
acquire中会判断:
而在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 (!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函数中,会判断,如果头尾节点不相同,并且头节点的后继为空或者头节点的后继中线程不是当前线程,就说明等待队列不为空。
如果等待队列为空的话,那么就通过CAS操作设置state,如果设置成功的话,那么就将当前线程设置成持有锁的线程,并且返回true,说明已经成功获取锁了。
否则,如果state不为0的话,那么则判断当前线程是不是就是已经持有锁的线程,如果是的话,那么就把当前状态+请求的值(1),然后设置当前的State值,饭后返回true,说明获取锁成功。否则,返回false,说明获取锁失败。
只有当获取锁失败,并且成功添加到链表尾部,才会被中断。