首页 > 其他 > 详细

ReentrantLock源码解析

时间:2021-04-24 20:38:49      阅读:31      评论:0      收藏:0      [点我收藏+]

 

 

 

 

 

 

 

 

 

 

ReentrantLock继承,组合。ReentrantLock实现了Lock接口,持有Sync实例,Sync的抽象父类是AbstractQueuedSynchronizer(以下称为AQS)AQS继承自AbstractOwnableSynchronizer(以下称之为AOS)AOS中只有一个成员变量Thread,当前持有锁的线程。

Sync有两个实现分别为NonfairSync非公平锁,FairSync公平锁。无参构造器默认为非公平锁,可以通过有参构造使用公平锁。

class ReentrantLock implements Lock, java.io.Serializable{
    private final Sync sync;
    abstract static class Sync extends AbstractQueuedSynchronizer{}
    static final class NonfairSync extends Sync{}
    static final class FairSync extends Sync{}      
}

public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable{}

public abstract class AbstractOwnableSynchronizer implements java.io.Serializable{
    private transient Thread exclusiveOwnerThread;
}
  public ReentrantLock() {
        sync = new NonfairSync();
    }
 public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }

加锁代码,先看公平锁,假设现在只有一条线程获取锁,还原获取锁成功的步骤。

 public void lock() {
        sync.lock();
    }
final void lock() {
    acquire(1);//AQS中
}
//AQS中
public final void acquire(int arg) {
        if (!tryAcquire(arg) &&
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
        protected final boolean tryAcquire(int acquires) {//入参1,尝试获取锁操作。
            final Thread current = Thread.currentThread();//当前线程。
            int c = getState();//AQS中的变量,默认为0,表示锁未被占用。
            if (c == 0) {//能进来说明当前锁未被占用。
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);//把当前线程设置到AOS中,占有锁成功。
                    return true;//返回成功。
                }
            }
            else if (current == getExclusiveOwnerThread()) {//getExclusiveOwnerThread从AOS中获取当前持有锁的线程是不是当前线程。
                int nextc = c + acquires;//重入锁+1。
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);//设置锁占用标记。
                return true;//返回成功。
            }
            return false;//返回失败。
        }
//AQS
public final boolean hasQueuedPredecessors() {
        Node t = tail; //将等待获取锁的线程封装到Node中,在AQS中有尾部,头部两个链表指针。
        Node h = head;
        Node s;
     //h!=t表示链表有元素,h.next==null表示链表中只有一个元素,链表中唯一的元素不是当前线程。
return h != t &&((s = h.next) == null || s.thread != Thread.currentThread()); } //AQS protected final boolean compareAndSetState(int expect, int update) { //CAS操作。成员变量state为1,不了解Unsafe的可以看上一篇博客。 return unsafe.compareAndSwapInt(this, stateOffset, expect, update); } //AOS protected final void setExclusiveOwnerThread(Thread thread) { exclusiveOwnerThread = thread;//设置当前线程为独占线程
}

还原锁获取失败的步骤。

 

final void lock() {
     acquire(1);
}

 

public final void acquire(int arg) {
      //tryAcquire返回false取反为true。执行&&后操作,Node EXCLUSIVE = null。这是Node内部类中的成员变量。 if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }

 

 protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();//有线程持有锁当前state!=0
            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;
}

 

    private Node addWaiter(Node mode) {
//Node(Thread thread, Node mode) {this.nextWaiter = mode;this.thread = thread;}
     //构造一个Node对象,入参为当前线程和一个空的Node,空的Node为下一个等待线程。
Node node = new Node(Thread.currentThread(), mode); Node pred = tail;//获取等待链表中最后一个节点。 if (pred != null) {//如果尾部节点存在 node.prev = pred;//将尾部节点设置为新节点的prev。
   //private final boolean compareAndSetTail(Node expect, Node update) {return unsafe.compareAndSwapObject(this, tailOffset, expect, update);}
       // CAS操作,将新节点设置为tail.这个操作是可能失败的。例如有其他线程创建了newNode替换了tail。 if (compareAndSetTail(pred, node)) { pred.next = node;//如果CAS操作成功,将新节点设置为上一个尾部节点的next return node;//返回新的tail } } enq(node); return node; }

 

 

 

    private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node()))
                    tail = head;
            } else {
                node.prev = t;
                if (compareAndSetTail(t, node)) {
                    t.next = node;
                    return t;
                }
            }
        }
    }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

,这个操作是可能失败的。

ReentrantLock源码解析

原文:https://www.cnblogs.com/zumengjie/p/14697589.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!