7 java并发编程实战 并发工具JUC之CountDownLatch

一、是什么?
是多线程控制JUt(java.util..)的一个工具类,它被称为 门阀 、 计数器 或者 闭锁。这个工具经常用来用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用)
【7java并发编程实战 并发工具JUC之CountDownLatch】 能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行 。它相当于是一个计数器,这个计数器的初始值就是线程的数量,每当一个任务完成后,计数器的值就会减一,当计数器的值为 0 时,表示所有的线程都已经任务了,然后在上等待的线程就可以恢复执行接下来的任务 。
二、类说明和原理1、大概源码
1、构造函数:
初始化的时候,需要提供一个整形数字count,数字代表着线程需要调用()方法的次数,当计数为0时,线程才会继续执行await()方法后的其他内容 。(int count)
2、:
返回当前的计数count值
3、 void ()
调用此方法后,会减少计数count的值 。递减后如果为0,则会释放所有等待的线程
4、 void await()
调用对象的await方法后 。会让当前线程阻塞,直到计数count递减至0 。
如果当前线程数大于0,则当前线程在线程调度中将变得不可用,并处于休眠状态,直到发生以下两种情况之一:
1、调用()方法,将计数count递减至0 。
2、当前线程被其他线程打断
5、await(long ,unit)
同时await还提供一个带参数和返回值的方法 。
如果计数count正常递减,返回0后,await方法会返回true并继续执行后续逻辑 。
或是,尚未递减到0,而到达了指定的时间间隔后,方法返回false 。
如果时间小于等于0,则此方法不执行等待 。
2、原理
从源码可以看出,是依赖于来实现这一系列逻辑的 。
队列同步器 是一个用来构建锁和同步器的框架,它在内部定义了一个被标识为的名为state的变量,用来表示同步状态 。
多个线程之间可以通过AQS来独占式或共享式的抢占资源 。
并且它通过内置的FIFO队列来完成线程的排队工作 。
中的Sync会优先尝试修改state的值,来获取同步状态 。例如,如果某个线程成功的将state的值从0修改为1,表示成功的获取了同步状态 。这个修改的过程是通过CAS完成的,所以可以保证线程安全 。
反之,如果修改state失败,则会将当前线程加入到AQS的队列中,并阻塞线程 。
三、1、join阻塞等待线程完成
使用join保证线程一、线程二执行完之后,再执行.out.("主线程")
具体请看《线程同步机制:彻底搞懂相关方法wait、join、sleep、》
package com.javademo.demo.jucdemo;import java.util.concurrent.CountDownLatch;public class CountDownLatchDemoJoin {public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(new Worker1());Thread thread2 = new Thread(new Worker2());thread1.start();thread2.start();thread1.join();thread2.join();System.out.println("主线程结束....");}private static class Worker1 implements Runnable {@Overridepublic void run() {System.out.println("-线程1执行");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}finally {System.out.println("线程1完成--我休眠5秒");}}}private static class Worker2 implements Runnable {@Overridepublic void run() {System.out.println("-线程2执行");try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}finally {System.out.println("线程2完成--我休眠3秒");}}}}
打印结果如下:
可以看出2个线程是并行执行的 。启动顺序,并不和执行完毕的顺序一致,但可以明确的是,主线程为一直阻塞,直到2个线程执行完毕 。