java调用一个方法后怎么继续执行不等待该方法的返回_深入分析Java并发工具类CountDownLatch...

1.什么是CountDownLatch

ae6eca1410a34f73dab1accda91d7847.png

顾名思义,CountDownLatch是一个倒计时器。

适用于多线程中,一个线程需要等待其他线程到达指定状态后再继续执行。

举个场景例子,火箭发射。需要3个步骤

1.设定倒计时的时间

2.等待倒计时完成

3.发射

我们用代码来实现一下这个功能

c7455d945e05b98200bdce7e6c045ea3.png

执行结果

bef0a9f192b10ae9925ea464bb1b1056.png

2.CountDownLatch的使用方法

就如同举的场景示例一样,CountDownLatch的使用方式也是分3个步骤

1.实例化一个CountDownLatch,并且设置计数

2.进行倒计时的线程,在到达指定状态的时候,调用实例的countdown方法,进行倒计数

3.需要等待的线程调用CountDownLatch实例的await方法,当计数归0时继续执行后续动作

3.源码分析

同样是按照步骤来看

e8726729a9a92f32ed191d1ff4f91d55.png

1.构造函数

如上图所示,CountDownLatch中有个内部类Sync继承了aqs。CountDownLatch只有一个带count的构造函数,这个count是用于初始化aqs的state,且该state是violate的(关于violate可以参考这篇文章Java多线程系列——volatile关键字),因此可以保证多线程环境下的可见。

13fc2c63cfbbecbd0d836b1b2a38da3f.png
a2aaf8c9ae0b1de3a137274b2773314b.png
ec60e01af97fddb33678083b4578429b.png

2.await方法

await是最核心也是最重的方法。

548713fb600e73df81e6d2de2a201bff.png

可以看到await方法是调用的sync的acquireSharedInterruptibly,即支持线程中断式地获取共享锁资源

92f88d5d5ecda554974b2886da1e7718.png
695569c5e0387c1ac23a978156026918.png
f2d8a9ded46b7c8e3e47e6da6722393d.png
88aab311b599317e46cc6df638b4d7cc.png
320c8b56d4b468de2d633eb23728e6ce.png
97c9b03b0e88f5d9d95a49e97cdef6a6.png

acquireSharedInterruptibly分为两个主要步骤

1.1尝试获取共享资源,即初始化时设置的state是否已经倒计时到0

1.2获取共享资源失败后执行支持线程中断的获取共享锁资源

我们可以这样简单的理解,await方法的本质就是查看state是否归0,归0就直接结束。如果不归0就继续等到state归0,如果知道state归0呢,那就是死循环查询加主动等待的搭配操作。

state尚未归零则执行支持线程中断的获取共享锁资源,正如上面所说死循环查询加主动等待的搭配操作。和aqs的思想一样

2.1插入一个共享模式的节点到队尾

2.2开启死循环查询。因为只有前继前节点是头结点才可以尝试获取共享资源

2.3如果前继前节点是头结点,并且获取到state已经归0。则将该节点设置为头结点,并且传播到后继节点,即如果后继节点是共享模式,且waitStatus正常,则唤醒该节点的线程。

waitStauts主要有以下几个值

CANCELLED=1 线程已经被取消

SIGNAL=-1 后续线程需要被唤醒

CINDITION=-2 线程在等待某个条件

PROPAGATE=-3 下一个AcquireShared应无条件传播

a7e493fd36b49d3c9127c501d42f0c6c.png

2.4如果前继前节点不是头结点或者state计数尚未归零则park当前线程

3.1查询是否可以park当前线程,前继节点需要为SIGNAL

bfff9adeb475df712f44d37bcc08a2d0.png

3.2park当前线程,并且返回线程状态是否被打断

3.countdown方法

countdown方法就很好猜了

1.递减state

2.当state归零的时候唤醒node队列中的状态为SIGNAL(SIGNAL是在判断是否需要park的时候设置的)的线程

2c246bab86fdb6b164d7c9b72f5d15f7.png
f91b24248f8ee6c8e977accc47f23c07.png
59bd650c108b7de58ef61ab178961d22.png