AbstractQueuedSynchronizer(六)——release

来源:互联网 发布:王珊数据库第五版ppt 编辑:程序博客网 时间:2024/05/17 10:42

/**     * Releases in exclusive mode.  Implemented by unblocking one or     * more threads if {@link #tryRelease} returns true.     * This method can be used to implement method {@link Lock#unlock}.     *     * @param arg the release argument.  This value is conveyed to     *        {@link #tryRelease} but is otherwise uninterpreted and     *        can represent anything you like.     * @return the value returned from {@link #tryRelease}     */    public final boolean release(int arg) {        if (tryRelease(arg)) {            Node h = head;            if (h != null && h.waitStatus != 0)                unparkSuccessor(h);            return true;        }        return false;    }
1. 尝试释放状态<br/>

如果tryRelease成功,判断当前头结点的状态,如果头结点不为null,而且状态不是0(已经被初始化过),进行unpark操作。

这说明头结点的后继节点正在等待获取该锁。之前该后继节点在尝试获取锁的时候,将其前驱节点的状态改为了SIGNAL。

2.{@link java.util.concurrent.locks.AbstractQueuedSynchronizer#unparkSuccessor}<br/>

获取当前节点的后继节点,如果满足状态,那么进行唤醒操作,如果没有满足状态(比如被取消),从尾部开始找寻符合要求的节点并将其唤醒

/**     * Wakes up node's successor, if one exists.     *     * @param node the node     */    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)            compareAndSetWaitStatus(node, 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 t = tail; t != null && t != node; t = t.prev)                if (t.waitStatus <= 0)                    s = t;        }        if (s != null)            LockSupport.unpark(s.thread);    }
3. 唤醒当前节点的后继节点所包含的线程<br/>

通过LockSupport的unpark方法将休眠中的线程唤醒,让其继续在acquireQueued等自旋等待锁的方法中acquire锁(状态)。
0 0
原创粉丝点击