可重入锁源码分析

ReentrantLock实现了Lock,初始化时可选择FairSync、NonfairSync。Sync继承了AbstractQueuedSynchronizer。AbstractQueuedSynchronizer的state:0表示未持有锁、>=1表示持有锁、>1表示锁被重入。AbstractQueuedSynchronizer用双向链表存储抢占锁的Node(AbstractQueuedSynchronizer的静态内部类,存有前驱Node、后继Node、线程)。

加锁

	// ReentrantLock里的方法
	public void lock() {
        sync.acquire(1);
    }
    // AQS里的方法
    public final void acquire(int arg) {
    // 尝试获取锁
        if (!tryAcquire(arg) &&
        // 线程未获取到锁
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
            selfInterrupt();
    }
    private Node addWaiter(Node mode) {
        Node node = new Node(mode);
// 线程未获取到锁,就将节点加入队列中(尾插的方式)
        for (;;) {
            Node oldTail = tail;
            if (oldTail != null) {
                node.setPrevRelaxed(oldTail);
                if (compareAndSetTail(oldTail, node)) {
                    oldTail.next = node;
                    return node;
                }
            } else {
            // 没有队列就创建(Node:head、tail)
                initializeSyncQueue();
            }
        }
    }
    final boolean acquireQueued(final Node node, int arg) {
        boolean interrupted = false;
        try {
            for (;;) {
            // 前一个节点是头节点就尝试获取锁
                final Node p = node.predecessor();
                if (p == head && tryAcquire(arg)) {
                // 获取了锁就替换头节点为当前节点
                    setHead(node);
                    p.next = null; // help GC
                    return interrupted;
                }
                // 前一个节点不是头节点或者获取锁失败就判断是否应挂起当前线程,应该挂起就挂起
                if (shouldParkAfterFailedAcquire(p, node))
                    interrupted |= parkAndCheckInterrupt();
            }
        } catch (Throwable t) {
        // 有异常或错误就取消获取锁,该标记中断就标记中断
            cancelAcquire(node);
            if (interrupted)
                selfInterrupt();
            throw t;
        }
    }
    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
        int ws = pred.waitStatus;
        if (ws == Node.SIGNAL)
        // 前一个节点是需要被唤醒的节点,就安全地挂起当前线程
            /*
             * This node has already set status asking a release
             * to signal it, so it can safely park.
             */
            return true;
        if (ws > 0) {
        // 前一个节点是被取消的,就删除前一个节点,再看下一个,还是被取消的就继续删除,直到前一个节点不是被取消的
            /*
             * Predecessor was cancelled. Skip over predecessors and
             * indicate retry.
             */
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);
            pred.next = node;
        } else {
        // 前一个节点的等待状态是默认的或者传播,就设置当前节点是需要被唤醒的
            /*
             * waitStatus must be 0 or PROPAGATE.  Indicate that we
             * need a signal, but don't park yet.  Caller will need to
             * retry to make sure it cannot acquire before parking.
             */
            pred.compareAndSetWaitStatus(ws, Node.SIGNAL);
        }
        return false;
    }

AbstractQueuedSynchronizer的Node的waitStatus默认是0。CANCELLED:1表示取消。SIGNAL:-1表示需要被唤醒。CONDITION:-2表示在等待条件。PROPAGATE:-3表示下一个获取共享锁的线程应该无条件传播。

非公平同步器尝试获取锁

    		// 非公平方式尝试获取锁
            final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
            // 未持有锁就持有锁
            // CAS方式将state改0为1
                if (compareAndSetState(0, acquires)) {
                // 记录持有互斥锁的线程exclusiveOwnerThread
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            // 持有锁的线程是当前线程
            else if (current == getExclusiveOwnerThread()) {
            // state + 1
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

公平同步器尝试获取锁

        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
            // 比非公平方式多了hasQueuedPredecessors():字面意思:是否有被排列的前驱,也就是队列中是否有线程等待,有就获取不到锁,公平锁:先到先得
                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;
        }
    }

解锁

    public void unlock() {
        sync.release(1);
    }
    public final boolean release(int arg) {
        if (tryRelease(arg)) {
            Node h = head;
            if (h != null && h.waitStatus != 0)
                unparkSuccessor(h);
            return true;
        }
        return false;
    }
        protected final boolean tryRelease(int releases) {
        // state - 1。如果-1后等于0,设置当前拥有锁的线程为null。
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }
    private void unparkSuccessor(Node node) {
        /*
         * If status is negative (i.e., possibly needing signal) try
         * to clear in anticipation of signalling.  It is OK if this
         * fails or if status is changed by waiting thread.
         */
        int ws = node.waitStatus;
        if (ws < 0)
            node.compareAndSetWaitStatus(ws, 0);

        /*
         * Thread to unpark is held in successor, which is normally
         * just the next node.  But if cancelled or apparently null,
         * traverse backwards from tail to find the actual
         * non-cancelled successor.
         */
        Node s = node.next;
       // 下一个节点为空或者被取消
        if (s == null || s.waitStatus > 0) {
            s = null;
            // 从尾部开始查找不为空的节点
            for (Node p = tail; p != node && p != null; p = p.prev)
                if (p.waitStatus <= 0)
                    s = p;
        }
        if (s != null)
        // 唤醒下一个节点或者从尾部开始不是被取消的节点的线程
            LockSupport.unpark(s.thread);
    }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风铃峰顶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值