温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

发布时间:2020-07-20 09:53:46 来源:网络 阅读:706 作者:shayang88 栏目:编程语言

1、CountDownLatch介绍

1.1 CountDownLatch的使用,请参考文章 多线程(七、同步计数器-CountDownLatch

2、案例分析

2.1 说明:

1、Thread-1执行await,等待主线程放行;
2、Thread-2执行await,等待主线程放行;
3、主线程执行countDown()放行。

3、源码分析

3.1 CountDownLatch的构造函数和如何使用AQS的同步状态:

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)
多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

1、CountDownLatch的初始计数器就是直接设置AQS的同步状态值state
2、countDown就是对state执行减1
3、当state为0的时候,放行。

3.2 Thread-1调用await

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

3.2.1 就是调用AQS的acquireSharedInterruptibly方法

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

3.2.2 tryAcquireShared的实现要比ReentrantLock简单很多

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

只要state是0,则所有获取资源的申请都会成功,这就是共享锁的含义。

3.2.3 如果主线程不放行,state不等于0,,申请失败,会执行doAcquireSharedInterruptibly

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

此时,自旋获取一次也会失败,会进行阻塞,进入【等待队列】

3.3 Thread-2调用await,结果同上,Thread-2也进入【等待队列】

3.4 主线程放行countDown()

3.4.1 countDown()

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

tryReleaseShared方法

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

然后执行doReleaseShared,唤醒Thread-1

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

Thread-1被唤醒后,从阻塞的地方继续执行,重新获取资源,此时state=0,则会获取成功

多线程(十二、AQS原理-CountDownLatch基于AQS的共享实现)

然后执行:setHeadAndPropagate方法把ThreadA结点变为头结点,并根据传播状态判断是否要唤醒并释放后继结点
private void setHeadAndPropagate(Node node, int propagate) {
        Node h = head; // Record old head for check below
        setHead(node);//设置当前节点为头节点

        if (propagate > 0 || h == null || h.waitStatus < 0 ||
                (h = head) == null || h.waitStatus < 0) {
            Node s = node.next;
            if (s == null || s.isShared()) //后继节点如果是共享的,则依次唤醒后继节点,这就是共享的原理
                doReleaseShared();
        }
    }

3.5 Thread-1会继续唤醒Thread-2,Thread-2继续执行,会继续唤醒后续共享节点,此时后面没有节点了,程序完成。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI