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. sqlserver表被锁了,解锁方法,删除锁的方法

    -- 查询死锁select        request_session_id spid,       OBJECT_NAME(resource_associated_entity_id) table ...

  2. 伟程君解决端口被占用问题(接口jmeter 本地端口被占用完了,jmeter报错的问题)(亲测是可以的)

    1.在目录下创建文件local.conf(没有就创建目录和文件) touch /etc/sysctl.d/local.conf mkdir(创建文件夹) touch(创建文件) 2.往local.co ...

  3. TensorFlow.js-机器学习

    一.参考学习 https://blog.csdn.net/Quincylk/article/details/85340004 http://www.tensorfly.cn/tfdoc/get_sta ...

  4. 【SSH进阶之路】Spring的IOC逐层深入——Spring的IOC原理[通俗解释一下](三)

    1. IoC理论的背景我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图1:软件系统中耦合的对象 如果我们打开机械 ...

  5. 基于thinkphp5框架做一个可以区别开发、测试、生产三种环境的配置加载

    在日常的开发测试中我们经常会遇到本地开发和测试或者线上配置参数不同的场景,必要你要是使用一个三方的支付,它的本地测试和线上的key值或者账号存在不同.最基本的做法是本地用测试参数,提交到测试的时候再改 ...

  6. 2019暑假牛客多校训练-第八场-C-CDMA(递归、水题)

    观察前3组可以推出递归规律,生成下一个类型时,每行copy自身与自身相反. 题目描述 Gromah and LZR have entered the third level. There is a b ...

  7. 从GitLab上创建分支本地拉取项目和提交项目详解

    很多公司前端项目都是部署在GitLab上的,今天我要分享的就是如何从GitLab上创建新的分支并在本地拉取和提交项目 一.在GitLab上面创建自己新的分支 首先你得注册一个账号,登陆之后进入项目Pr ...

  8. SpringBoot配置文件敏感信息加密-jasypt

    使用过SpringBoot配置文件的朋友都知道,资源文件中的内容通常情况下是明文显示,安全性就比较低一些.打开application.properties或application.yml,比如mysq ...

  9. 1. Spark SQL概述

    1.1 什么是Spark SQL Spark SQL是Spark用来处理结构化数据的一个模块,它提供了一个编程抽象叫做DataFrame并且作为分布式SQL查询引擎的作用 它是将Hive SQL转换成 ...

  10. Android--卸载应用

    获取应用列表: List<PackageInfo> packages = getPackageManager().getInstalledPackages(0); for (Package ...