Latch:门闩。一种线程通信的方式;当程序不涉及同步,仅仅需要线程通信的时候,使用synchronize或者lock的线程通信等待唤醒机制,就显得太重了;

这时候,可以考虑使用信号量类:CountDownLatch,cylicbarrier,semaphore

CountDownLatch是一个多线程控制工具类。可以实现计数器的功能。

CountDownLatch的两种应用场景:(不能实现多个线程顺序执行!)

1. 让某线程等待其他线程执行完毕,再开始执行;

2. 让多个线程同时开始并行执行;

构造器:

// 传入一个count,指定要等待的线程个数
public CountDownLatch(int count)

主要方法:

// 调用await的线程会被挂起,直到count==0,才会继续执行。
public void await(){}; // 等待一定时间,count还没有为0,线程继续执行
public boolean await(long timeout, TimeUnit unit){}; // 将count值减1,一般在线程执行结束,调用此方法,代表计数器减1.
public void countDown() {};

第一种场景:

让某线程,等待n个线程执行结束,再继续执行;

创建一个Task类

public class Task implements Runnable {
private String name;
private CountDownLatch latch;
// 线程需要CountDownLatch对象
public Task(CountDownLatch latch, String name) {
this.latch = latch;
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000);
System.out.println(this.name + " Over");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
latch.countDown(); // 执行完毕,计数器减一
}
}
}

主方法:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchTest {
public static void main(String[] args) throws InterruptedException { CountDownLatch latch = new CountDownLatch(3);
Task task_A = new Task(latch, "A");
Task task_B = new Task(latch, "B");
Task task_C = new Task(latch, "C");
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.submit(task_A);
executorService.submit(task_B);
executorService.submit(task_C);
executorService.shutdown();
// 挂起mian线程,等待计数器置0,也就是三个线程执行完毕。
latch.await();
System.out.println(Thread.currentThread().getName());
}
}

运行结果:

A Over
B Over
C Over
main // 等待三个线程执行完毕,main线程执行

第二种场景:

其实跟第一种,基本一样,只不过反着来;await所有的用户线程,让main线程先行,计数器减一,为0;接着用户线程就会一起启动;

这个方式,对于并发其实没有什么用,主要用于并行的场景;真正的同时启动多个线程。

【JUC】7.CountDownLatch的更多相关文章

  1. 【1】【JUC】JDK1.8源码分析之ReentrantLock

    概要: ReentrantLock类内部总共存在Sync.NonfairSync.FairSync三个类,NonfairSync与FairSync类继承自Sync类,Sync类继承自AbstractQ ...

  2. 【JUC】JDK1.8源码分析之ArrayBlockingQueue(三)

    一.前言 在完成Map下的并发集合后,现在来分析ArrayBlockingQueue,ArrayBlockingQueue可以用作一个阻塞型队列,支持多任务并发操作,有了之前看源码的积累,再看Arra ...

  3. 【1】【JUC】JDK1.8源码分析之ArrayBlockingQueue,LinkedBlockingQueue

    概要: ArrayBlockingQueue的内部是通过一个可重入锁ReentrantLock和两个Condition条件对象来实现阻塞 注意这两个Condition即ReentrantLock的Co ...

  4. 【JUC】阻塞队列&生产者和消费者

    阻塞队列 线程1往阻塞队列添加元素[生产者] 线程2从阻塞队列取出元素[消费者] 当队列空时,获取元素的操作会被阻塞 当队列满时,添加元素的操作会被阻塞 阻塞队列的优势:在多线程领域,发生阻塞时,线程 ...

  5. 【JUC】JDK1.8源码分析之CountDownLatch(五)

    一.前言 分析完了CyclicBarrier后,下面分析CountDownLatch,CountDownLatch用于同步一个或多个任务,强制他们等待由其他任务执行的一组操作完成.CountDownL ...

  6. 【JUC】CountDownLatch

    因为在调用端的异步中,需要调用其他多个服务获取数据再汇总结果返回,所以用到了CountDownLatch CountDownLatch的概念 CountDownLatch是一个同步工具类,用来协调多个 ...

  7. 【JUC】CountDownLatch和Java枚举的使用例子

    public enum CountryEnum { ONE(1,"春"), TWO(2,"夏"), THREE(3,"秋"), FOUR(4 ...

  8. 【JUC】JUC锁框架综述

    一.前言 在分析完了集合框架后,很有必要接着分析java并发包下面的源码,JUC(java.util.concurrent)源码也是我们学习Java迈进一步的重要过程.我们分为几个模块进行分析,首先是 ...

  9. 【1】【JUC】Condition和生产者消费者模型

    本篇文章将介绍Condition的实现原理和基本使用方法,基本过程如下: 1.Condition提供了await()方法将当前线程阻塞,并提供signal()方法支持另外一个线程将已经阻塞的线程唤醒. ...

随机推荐

  1. 002 vue-resource

    一:概述 1.说明 https://github.com/pagekit/vue-resource 2.使用方法 Vue.http.get('/someUrl', [config]).then(suc ...

  2. ISO/IEC 9899:2011 引言

    引言 1.伴随着新的设备以及扩展字符集的引入,可能会将新的特性添加到此国际标准中.在此语言和库条款中的子条款提醒了实现者与程序员可能会与将来所新增特性产生冲突的用法,尽管它们现在本身是合法有效的. 2 ...

  3. 认领该应用 apk空白包签名 方法

    起因: apicloud开发的项目,上架应用宝市场,被要求做这个 解决方法: 下载签名工具,并解压缩.解压缩.解压后是两个文件夹,选择keystore签名工具. 下载地址: linux 签名工具(命令 ...

  4. time命令_Linux time命令:测量命令的执行时间或者系统资源的使用情况(转)

    原文地址:http://m.biancheng.net/linux/time.html 这里我们要学习的 time 命令是用来测量 Linux 程序执行时间的命令,而不是用来显示系统时间的命令.不是吧 ...

  5. python 传入任意多个参数(方法调用可传参或不传参)

    1.可传参数与不传参数,在定义中给参数设置默认值 class HandleYmal: """ 获取测试环境的配置 """ def __ini ...

  6. 微设计基础架构(MDI)

    微设计基础架构(MDI) 了解微设计基础架构(MDI)的概念,它们如何帮助开发,以及它们与DevOps和微服务等技术的关系. 技术决策既困难又严肃,可以决定项目的成败.如何找到合适的技术栈?“微设计基 ...

  7. python tkinter中的事件绑定

    一个Tkinter主要跑在mainloop进程里.Events可能来自多个地方,比如按键,鼠标,或是系统事件. Tkinter提供了丰富的方法来处理这些事件.对于每一个控件Widget,你都可以为其绑 ...

  8. layui的select监听

    首先,select一定要放在<form class="layui-form" ></form>里面 然后,加监听<select id="id ...

  9. Git 工作流之 GitFlow

    GitFlow学习: 先学习这篇:点击打开链接 Gitflow工作流是经典模型,体现了工作流的经验和精髓.随着项目过程复杂化,会感受到这个工作流中深思熟虑和威力. ////////////////// ...

  10. Linux定时自动备份oracle数据库

    1.在服务器创建备份目录,并赋予权限mkdir -p /backup/P_DATA #新建shell脚本存放路径mkdir -p /backup/P_DB_BACK  #新建Oracle数据库备份目录 ...