高级JAVA - 多线程之CountDownLatch
package com.xbz.thread.juc.countDownLatch;import java.util.concurrent.CountDownLatch;/*** @title CountDownLatch类的应用* CountDownLatch类位于java.util.concurrent(简称juc)包下 , 它是一个同步工具类 , 利用它可以实现类似计数器的功能* 比如有一个任务A , 它要等待其他4个任务结束执行之后才能执行 , 此时就可以利用CountDownLatch来实现这种功能了* 主要用来协调多个线程之间的同步 , 或者说起到线程之间的通信 ( 而不是用作互斥的作用 )* CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后 , 再继续执行 . 使用一个计数器进行实现 .* 计数器初始值为线程的数量 .* 当每一个线程完成自己任务后 , 计数器的值就会减一(手动) .* 当计数器的值为0时 , 表示所有的线程都已经完成了任务 , 然后在CountDownLatch上等待的线程就可以恢复执行任务** CountDownLatch类只提供了一个构造器 :* public CountDownLatch(int count)//参数count为计数值 , 即需要先执行几个线程** CountDownLatch类的主要方法 :* void await()//调用await()方法的线程会被挂起 , 它会等待直到count值为0才继续执行* boolean await(long timeout, TimeUnit unit)//和await()类似 , 只不过等待一定的时间后count值还没变为0的话也会继续执行* void countDown()//将count值减1* CountDownLatch的不足* CountDownLatch是一次性的 , 计数器的值只能在构造方法中初始化一次 , 之后没有任何机制再次对其设置值 , 当CountDownLatch使用完毕后 , 它不能再次被使用* @author Xingbz* @createDate 2018-7-18*/
public class MainDemo {public static void main(String[] args) throws Exception {
// demo1();demo2();}/*** @title CountDownLatch典型用法1* @description 某一线程在开始运行前等待n个线程结束执行 . * 将CountDownLatch的计数器初始化为n new CountDownLatch(n) , * 每当一个任务线程结束执行 , 就将计数器减1 countdownlatch.countDown() , * 当计数器的值变为0时 , 在CountDownLatch上 await() 的线程就会被唤醒 . * 一个典型应用场景就是启动一个服务时 , 主线程需要等待多个组件加载完毕 , 之后再继续执行 . * @author Xingbz*/public static void demo1() throws Exception {
// final CountDownLatch latch = new CountDownLatch(2);//2个线程后开始执行final CountDownLatch latch = new CountDownLatch(2) {//此处是为了演示线程过程特意重写了await方法, 实际应用如上声明即可@Overridepublic void await() throws InterruptedException {System.out.println("当前线程 : " + Thread.currentThread().getName() + " 进入阻塞状态 . 当前计数器 : " + this.getCount());super.await();}};//2个线程后开始执行runThread("线程1", 2000L, latch);runThread("线程2", 3000L, latch);System.out.println("等待2个子线程结束执行...");latch.await();//当前线程挂起 , 直到计数器为0
// latch.await(20, TimeUnit.SECONDS);//最多阻塞20S , 20S后即使计数器不是0也继续往下执行System.out.println("2个子线程已经结束执行");System.out.println("继续执行主线程");}/*** @title CountDownLatch典型用法2* @description* 实现多个线程开始执行任务的最大并行性 . * 注意是并行性 , 不是并发 , 强调的是多个线程在某一时刻同时开始执行 . * 类似于赛跑 , 将多个线程放到起点 , 等待发令枪响 , 然后同时开跑 . * 做法是额外初始化一个共享的CountDownLatch(1) , 将其计数器初始化为1 , * 多个线程在开始执行任务前首先 coundownlatch.await() , 当主线程调用 countDown() 时 , 计数器变为0 , 多个线程同时被唤醒* @author Xingbz*/public static void demo2() throws Exception {CountDownLatch countDown = new CountDownLatch(1);CountDownLatch latch = new CountDownLatch(5);for (int i = 0; i < 5; ++i) {// 依次创建并启动处于等待状态的5个线程runThread("线程" + (i + 1), 2000L, countDown, latch);}System.out.println("执行了5个线程并进入了阻塞状态 . 等待统一启动 . . . ");countDown.countDown();System.out.println("主控器结束计数 , 所有线程同时开始执行 . . .");latch.await();System.out.println("完成");}/*** @title 模拟启动一个子线程工作* @param threadName 线程名称* @param sleepTime 休眠时间* @param countDown 主控制器 CountDownLatch 负责所有线程启动后先进入阻塞 "预备" 状态* @param latch 辅控制器 CountDownLatch 负责所有线程执行完成后继续运行主线程* @author Xingbz*/private static void runThread(String threadName, Long sleepTime, CountDownLatch countDown, CountDownLatch latch) {Thread thread = new Thread(() -> {try {System.out.println("子线程[" + Thread.currentThread().getName() + "]准备执行");countDown.await();Thread.sleep(sleepTime);System.out.println("子线程[" + Thread.currentThread().getName() + "]正在执行");Thread.sleep(sleepTime);latch.countDown();//子线程结束执行 , latch计数器减1System.out.println("子线程[" + Thread.currentThread().getName() + "]结束执行 , latch计数器-1 . 当前计数器 : " + latch.getCount());} catch (InterruptedException e) {e.printStackTrace();}}, threadName);thread.start();}/*** @title 模拟启动一个子线程工作* @param threadName 线程名称* @param sleepTime 休眠时间* @param latch CountDownLatch* @author Xingbz*/private static void runThread(String threadName, Long sleepTime, CountDownLatch latch) {Thread thread = new Thread(() -> {try {System.out.println("子线程[" + Thread.currentThread().getName() + "]正在执行");Thread.sleep(sleepTime);latch.countDown();//子线程结束执行 , latch计数器减1System.out.println("子线程[" + Thread.currentThread().getName() + "]结束执行 , latch计数器-1 . 当前计数器 : " + latch.getCount());} catch (InterruptedException e) {e.printStackTrace();}}, threadName);thread.start();}
}
高级JAVA - 多线程之CountDownLatch相关推荐
- Java多线程之CountDownLatch用法
Java多线程之CountDownLatch用法 本文目录: CountDownLatch基本概念 CountDownLatch案例:6个同学陆续离开教室后班长才可以关门 CountDownLatch ...
- (十)java多线程之CountDownLatch
目录 引言 理论 例子 打赏 本人邮箱: kco1989@qq.com 欢迎转载,转载请注明网址 http://blog.csdn.net/tianshi_kco github: https://gi ...
- JAVA多线程之CountDownLatch
前序: 上周测试给开发的同事所开发的模块提出了一个bug,并且还是偶现. 经过仔细查看代码,发现是在业务中启用了多线程,2个线程同时跑,但是新启动的2个线程必须保证一个完成之后另一个再继续运行,才能消 ...
- java多线程之CountDownLatch倒数闸门
在多个线程进行协作时,一个常见的情景是一个线程需要等待另外的线程完成某些任务之后才能继续进行.在这种情况下,可以使用CountDownLatch类,CountDownLatch类相当于多个线程等待开启 ...
- JAVA多线程之wait/notify
本文主要学习JAVA多线程中的 wait()方法 与 notify()/notifyAll()方法的用法. ①wait() 与 notify/notifyAll 方法必须在同步代码块中使用 ②wait ...
- Java多线程之Callable、Future和FutureTask
Java多线程之Callable接口 自己想总结一下的,看到一篇总结的更好的博客,就转载了,突然感觉真轻松,哈哈哈哈 文章转载于:Matrix海子:Java并发编程:Callable.Future和F ...
- Java多线程之Synchronized和Lock的区别
Java多线程之Synchronized和Lock的区别 目录: 原始构成 使用方法 等待是否可以中断 加锁是否公平 锁绑定多个条件Condition 小结:Lock相比较Synchronized的优 ...
- Java多线程之CAS缺点
Java多线程之CAS缺点 目录: 循环时间开销很大 只能保证一个共享变量的原子操作 引来ABA问题及解决方案(重点) 1. 循环时间开销很大 通过看源码,我们发现有个do while,如果CAS失败 ...
- Java多线程之CAS深入解析
Java多线程之CAS深入解析 目录: CAS是什么 CAS底层原理Unsafe深入解析 CAS缺点 引子:蚂蚁花呗一面:讲一讲AtomicInteger,为什么要用CAS而不是synchronize ...
最新文章
- heroes 2 android,英雄出击2游戏下载-英雄出击2Heroes Strike2中文安卓版下载v0.0.5- 游侠下载站...
- 【转】医学影像技术(中国普通高等学校本科专业)
- 验证Vsphere 5 支持大于2TB磁盘
- netty的零拷贝、架构设计、ByteBuf扩容机制详解
- 【mysql基础知识】数据库中新建触发器,监控数据变化
- Android实战简易教程-第二十八枪(Uri转String型实例)
- 成功凤凰刷机刷出诺基亚E5系统版本042.014纯净简体中文版
- 菜鸟教程Python教程100例合集
- Seaweedfs安装配置使用及mount挂载
- oracle报内存不足,oracle 内存不足处理
- 双系统装完只能u盘启动_怎样用u盘安装双系统呢?
- 1001 害死人不偿命的(3n+1)猜想 (15 分) (MyFirstCSDNBlog~)
- 阿里TPP图化框架技术实践 — 打造算法在线服务领域极致开发体验与性能
- 区块链MMO游戏该如何设计Token经济?
- 如何解决MacBook休眠时耗电过大的问题
- 12Cr1MoVR是什么材质12Cr1MoVR钢板简介12Cr1MoVR化学成分钢板应用
- 数学建模-对策论模型
- 如何在文字上划横线_word怎么在字上划线的两种方法
- 【转载】sql 另一个安装程序实例已在运行
- Halcon 简单入门3D点云计算高度