ReentrantLock源码分析

来源:互联网 发布:淘宝卖家发快递3元包邮 编辑:程序博客网 时间:2024/06/06 23:50

公平锁的实现

Sync类继承自AbstractQueuedSynchronizer类。而FairSync类继承自Sync。

final void lock() {    acquire(1);  //会调到tryAcquire的方法}

重写了基类的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()) {        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() {        // 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());    }

这段代码是第一次在tryAcquire的时候判断:

  1. 当前队列中的头结点是否是第一个节点,且没有后续节点,即tail和head是同一个节点。
  2. 当前线程为头节点的第一个子节点,即node节点。
  3. 通过CAS操作将state赋值为1,没有tryAcquire成功的线程,则通过一个队列排队,等之前的线程释放锁之后再进行锁的获取。

非公平锁的实现

 非公平锁和公平锁代码差不多,来看看它的实现代码:
final void lock() {    if (compareAndSetState(0, 1))   //直接获取不需要排队        setExclusiveOwnerThread(Thread.currentThread());    else        acquire(1);}而它也同样重写了tryAcquire的实现方法:

protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
该nonfairTryAcquire方法是在Sync类中实现的:

 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;        }

可以看到非公平锁在第一次获取锁的时候就直接通过CAS操作看能不能拿到锁,拿到了就不去排队了,而在队列中的等待获取锁的线程还是在排队等候。
打个比方说有线程1、线程2、线程3,线程1获取了锁,线程2和3在排队,当线程1释放锁的时候,线程4也来竞争锁,此时,如果是非公平锁的话就直接不去队列里面判断了,线程4可以直接拿到锁。

原创粉丝点击