ReetrantLock源码解析

    技术2022-07-11  87

    1.Lock方法

    final void lock() { /** * cas方式将state标志位从0设置为1,设置成功的线程相当于拿到了锁 * 然后将ownerThread设置为当前线程 */ if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else //失败的线程进入acquire acquire(1); } public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(AbstractQueuedSynchronizer.Node.EXCLUSIVE), arg)) selfInterrupt(); } final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); //再次判断锁状态,如果没有被占用cas方式0-1,成功设置ownerThread返回 if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } //如果当前线程是持锁线程 else if (current == getExclusiveOwnerThread()) { //state++ int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } //其他失败线程直接return false; return false; } //失败的线程进入下面方法 private Node addWaiter(Node mode) { //封装node Node node = new Node(Thread.currentThread(), mode); Node pred = tail; //队列中已经有node if (pred != null) { node.prev = pred; //cas将node设置为tail节点 if (compareAndSetTail(pred, node)) { pred.next = node; return node; } } //队列为空或者cas失败 enq(node); return node; } //队列为空或者cas失败完全入队 private Node enq(final Node node) { for (;;) { Node t = tail; //队列为空应该设置头节点,因为头节点一直是持锁线程节点 if (t == null) { if (compareAndSetHead(new Node())) tail = head; } else {//不是空或者cas失败 循环入队 node.prev = t; if (compareAndSetTail(t, node)) { t.next = node; //返回当前节点的上一个节点 return t; } } } } //node表示入队节点的上一个节点 final boolean acquireQueued(final Node node, int arg) { boolean failed = true; try { boolean interrupted = false; for (;;) { //获取当前节点的上一个节点 final Node p = node.predecessor(); //如果p是head节点可以尝试获取锁(头节点任何时候都是持锁线程) if (p == head && tryAcquire(arg)) { //把当前节点设置为head头节点 setHead(node); p.next = null; // help GC failed = false; return interrupted; } //只有当前节点的上一个节点状态为-1才返回true,接下来会park //返回false进入下次循环 if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } finally { if (failed) cancelAcquire(node); } } private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { int ws = pred.waitStatus; //上一个节点状态为-1 表示可以被唤醒状态 if (ws == Node.SIGNAL) return true; if (ws > 0) {//表示当前节点的线程已经被cancel,从当前节点开始往前查找直到找到没有被cancel的节点 do { /** * pred = pred.prev 当前节点指向他的上一个节点 * node.prev = pred pred节点作为node的上一个节点 */ node.prev = pred = pred.prev; } while (pred.waitStatus > 0); //双向绑定 pred.next = node; } else { //将pred节点状态设置为signal compareAndSetWaitStatus(pred, ws, Node.SIGNAL); } return false; } //shouldParkAfterFailedAcquire==true才会park private final boolean parkAndCheckInterrupt() { LockSupport.park(this); return Thread.interrupted(); }
    Processed: 0.012, SQL: 9