美文网首页
AQS源码解析(7)release

AQS源码解析(7)release

作者: 三斤牛肉 | 来源:发表于2021-01-11 11:44 被阅读0次

    释放锁的核心函数release:

    public final boolean release(int arg) {
            if (tryRelease(arg)) {//同tryAcquire具体实现类有自己实现,后面看reentrantlock的实现
                Node h = head;
                if (h != null && h.waitStatus != 0)//head=null的情况只有一个线程进入,没有初始化队列,!=null至少说明队列被初始化过,但是是否有后续节点未知,waitStatus!=0说明下个节点是等待的
                    unparkSuccessor(h);//唤醒下个节点
                return true;
            }
            return false;
    }
    

    tryRelease比较简单,比较state的值是否减到0

    protected final boolean tryRelease(int releases) {
                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) {
            int ws = node.waitStatus;
            //ws小于0表示正常排队线程,先设置为0
            if (ws < 0)
                compareAndSetWaitStatus(node, ws, 0);
    
            Node s = node.next;
           //这里着实没想出什么时候s会null,除了手动去修改队列,我理解只是作者的保护
           //waitStatus>0表示下个线程是被cancel状态
           //进这个是从队尾开始找,找最近的正常排队的线程
            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);//唤醒下一个等待队列中的线程
     }
    

    相关文章

      网友评论

          本文标题:AQS源码解析(7)release

          本文链接:https://www.haomeiwen.com/subject/lzjzoktx.html