Java的concurrent包里面的CountDownLatch其实可以把它看作一个计数器,只不过这个计数器的操作是原子操作,同时只能有一个线程去操作这个计数器,也就是同时只能有一个线程去减这个计数器里面的值。
你可以向CountDownLatch对象设置一个初始的数字作为计数值,任何调用这个对象上的await()方法都会阻塞,直到这个计数器的计数值被其他的线程减为0为止。
CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。假如我们这个想要继续往下执行的任务调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。
举个例子,有三个工人在为老板干活,这个老板有一个习惯,就是当三个工人把一天的活都干完了的时候,他就来检查所有工人所干的活。记住这个条件:三个工人先全部干完活,老板才检查。所以在这里用Java代码设计两个类,Worker代表工人,Boss代表老板,具体的代码实现如下:
package org.zapldy.concurrent;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class Worker implements Runnable{
private CountDownLatch downLatch;
private String name;
public Worker(CountDownLatch downLatch, String name){
this.downLatch = downLatch;
this.name = name;
}
public void run() {
this.doWork();
try{
TimeUnit.SECONDS.sleep(new Random().nextInt(10));
}catch(InterruptedException ie){
}
System.out.println(this.name + "活干完了!");
this.downLatch.countDown();
}
private void doWork(){
System.out.println(this.name + "正在干活!");
}
}
package org.zapldy.concurrent;
import java.util.concurrent.CountDownLatch;
public class Boss implements Runnable {
private CountDownLatch downLatch;
public Boss(CountDownLatch downLatch){
this.downLatch = downLatch;
}
public void run() {
System.out.println("老板正在等所有的工人干完活......");
try {
this.downLatch.await();
} catch (InterruptedException e) {
}
System.out.println("工人活都干完了,老板开始检查了!");
}
}
package org.zapldy.concurrent;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CountDownLatchDemo {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(3);
Worker w1 = new Worker(latch,"张三");
Worker w2 = new Worker(latch,"李四");
Worker w3 = new Worker(latch,"王二");
Boss boss = new Boss(latch);
executor.execute(w3);
executor.execute(w2);
executor.execute(w1);
executor.execute(boss);
executor.shutdown();
}
}
当你运行CountDownLatchDemo这个对象的时候,你会发现是等所有的工人都干完了活,老板才来检查,下面是我本地机器上运行的一次结果,可以肯定的每次运行的结果可能与下面不一样,但老板检查永远是在后面的。
王二正在干活!
李四正在干活!
老板正在等所有的工人干完活......
张三正在干活!
张三活干完了!
王二活干完了!
李四活干完了!
工人活都干完了,老板开始检查了!
好了,就写到这里,睡觉去了!
分享到:
相关推荐
主要介绍了详解java CountDownLatch和CyclicBarrier在内部实现和场景上的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
CountDownLatch 实际应用描述代码注意事项 描述 使用CountDownLatch控制多线程获取数据,并汇集成一个集合返回。 代码 @ApiOperation(value = "Mis(时间推移)统计", notes = "Mis(时间推移)统计") @RequestMapping...
目录: 简介 1.1 并发编程与线程同步 1.2 CountDownLatch概述 ...CountDownLatch的其他应用场景 5.1 倒计时计时器 5.2 同时开始任务 5.3 等待多个资源就绪 CountDownLatch与CyclicBarrier的对比 最佳实践与注意事项
目录 CountDownLatch是什么? CountDownLatch如何工作? 在实时系统中的应用场景 应用范例 常见的面试题 代码样例
1、本资源包含并发编程基础知识的使用案例,包括:线程创建、Synchronized和Reentrantlock锁的使用、线程安全问题演示、Condition的应用、CountDownLatch的应用、Cyclicbarrier的应用、Semaphore的应用、线程池的...
15 applet java可以编写两类程序,applications和applet,applications可以在控制台直接运行,与其他高级编程语言没有太大区别,而java的特色在于它具有编制小应用程序的功能,applet可以在internet上传输并在兼容...
java 高并发应用场景
全部代码出自电子工业出版社夏先波的《Java JDK实例宝典》一书,本书以J2SE 5.0为开发环境,选取Java应用的典型实例,循序渐进地介绍了Java语言的各种开发方法和技巧,实例代码注释详细规范,思路清晰。 第1章 ...
CountDownLatch:可以使一个或多个线程等待一组事件发生 FutureTask *应用场景 (1)用作异步任务使用,且可以使用get方法获取任务的结果 (2)用于表示一些时间较长的计算 状态 ...
线程之间通信之join应用与实现原理剖析.mp4 ThreadLocal 使用及实现原理.mp4 并发工具类CountDownLatch详解.mp4 并发工具类CyclicBarrier 详解.mp4 并发工具类Semaphore详解.mp4 并发工具类Exchanger详解.mp4 ...
第35节线程之间通信之join应用与实现原理剖析00:10:17分钟 | 第36节ThreadLocal 使用及实现原理00:17:41分钟 | 第37节并发工具类CountDownLatch详解00:22:04分钟 | 第38节并发工具类CyclicBarrier 详解00:11:52...
CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程...
AQS相关应用(CountDownLatch、CyclicBarrier、Semaphore等),executor(ThreadPoolExecutor、ScheduledThreadPoolExecutor、FutureTask等),collection(ConcurrentHashMap、CopyOnWriteArrayList等), ...
源码详解CountDownLatch CountDownLatch,是一种常见同步器。其实现依赖于AQS(可以参考抽象队列式同步器AQS...import java.util.concurrent.CountDownLatch; public class Main{ //初始化构造,赋值计数器值 public s
第35节线程之间通信之join应用与实现原理剖析00:10:17分钟 | 第36节ThreadLocal 使用及实现原理00:17:41分钟 | 第37节并发工具类CountDownLatch详解00:22:04分钟 | 第38节并发工具类CyclicBarrier 详解00:11:52...
同步与异步 通常同步意味着一个任务的某个处理过程会对多个线程在用串行化处理,而异步则意味着某个处理过程可以允许多个线程同时处理。... CountDownLatch 应用场景:控制在一组线程操作执行完成之前当前线
未来的应用会逐步迁移到Java11. 因此Java8以前的API参考价值越来越弱, 因此本Repo不再更新, 一些内容将迁移到Java8上. 20180806 Java Concurrency in Practice 读书笔记和示例代码 包括 线程基础/同步sync/并发...
1) 现在有 T1、T2、T3 三个线程...13) 在 Java 中 CycliBarriar 和 CountdownLatch 有什么区别? 14) 什么是不可变对象,它对写并发应用有什么帮助? 15) 你在多线程环境中遇到的常见的问题是什么?你是怎么解决它的?