CountDownLatch:允许一条或多条线程等待其它线程中的一组操作完成后再继续执行。

在探究CountDownLatch之前,我们知道Thread的join也有类似功能,先看thread的join方法:

 1 public static void main(String[] args) throws InterruptedException{
2 Thread t1 = new Thread(new Runnable() {
3 @Override
4 public void run() {
5 System.out.println("i am t1");
6 }
7 });
8 Thread t2 = new Thread(new Runnable() {
9 @Override
10 public void run() {
11 try {
12 t1.join();
13 }
14 catch (InterruptedException e){}
15 System.out.println("i am t2");
16 }
17 });
18 Thread t3 = new Thread(new Runnable() {
19 @Override
20 public void run() {
21 try {
22 t2.join();
23 }
24 catch (InterruptedException e){}
25 System.out.println("i am t3");
26 }
27 });
28 t1.start();
29 t2.start();
30 t3.start();
31 }

Thread join方法原理:

源码中,可以看到join调用了Object的wait方法,是一个无限等待。

疑问:既然这里有wait,那notify去哪了?

原来在jvm源码中有这样一句:

 1 // 位于/hotspot/src/share/vm/runtime/thread.cpp中
2 void JavaThread::exit(bool destroy_vm, ExitType exit_type) {
3 // ...
4
5 // Notify waiters on thread object. This has to be done after exit() is called
6 // on the thread (if the thread is the last thread in a daemon ThreadGroup the
7 // group should have the destroyed bit set before waiters are notified).
8 // 看这里
9 ensure_join(this);
10
11 // ...
12 }
13
14
15 static void ensure_join(JavaThread* thread) {
16 // We do not need to grap the Threads_lock, since we are operating on ourself.
17 Handle threadObj(thread, thread->threadObj());
18 assert(threadObj.not_null(), "java thread object must exist");
19 ObjectLocker lock(threadObj, thread);
20 // Ignore pending exception (ThreadDeath), since we are exiting anyway
21 thread->clear_pending_exception();
22 // Thread is exiting. So set thread_status field in java.lang.Thread class to TERMINATED.
23 java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED);
24 // Clear the native thread instance - this makes isAlive return false and allows the join()
25 // to complete once we've done the notify_all below
26 java_lang_Thread::set_thread(threadObj(), NULL);
27
28 // 看这里
29 lock.notify_all(thread);
30
31 // Ignore pending exception (ThreadDeath), since we are exiting anyway
32 thread->clear_pending_exception();
33 }

回到CountDownLatch:

使用:

 1 public static void main(String[] args) throws InterruptedException{
2 CountDownLatch c2 = new CountDownLatch(1);//t2使用
3 CountDownLatch c3 = new CountDownLatch(1);//t3使用
4 Thread t1 = new Thread(new Runnable() {
5 @Override
6 public void run() {
7 System.out.println("i am t1");
8 c2.countDown();
9 }
10 });
11
12 Thread t2 = new Thread(new Runnable() {
13 @Override
14 public void run() {
15 try {
16 c2.await();
17 }
18 catch (InterruptedException e){}
19 System.out.println("i am t2");
20 c3.countDown();
21 }
22 });
23 Thread t3 = new Thread(new Runnable() {
24 @Override
25 public void run() {
26 try {
27 c3.await();
28 }
29 catch (InterruptedException e){}
30 System.out.println("i am t3");
31 }
32 });
33 t1.start();
34 t2.start();
35 t3.start();
36 }

CountDownLatch原理:

利用AQS,主线程(需要等待其它线程的线程)进入AQS队列中等待,前置线程通过State获取锁并执行任务,当State=0时即表示任务全部执行完毕。主线程唤醒。

await()方法 ==》

主线程入队等待:LockSupport.park()

countDown方法 ==》分成两步:

1,前置线程执行完释放锁,State-1;

2,一旦State=0,唤醒主线程。

可以看到,CountDownLatch更加灵活,Join方法必须等待前置线程执行完毕才能开始执行下一线程,中间过程无法控制;

而CountDownLatch的countDown方法可以自由的对任务片段进行控制。

JUC同步工具CountDownLatch的更多相关文章

  1. Java并发和多线程4:使用通用同步工具CountDownLatch实现线程等待

    CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown ...

  2. Java多线程_同步工具CountDownLatch

    概念:CountDownLatch是多线程里面一个类似于计数器的高级同步工具,它的初始值代表线程的数量,当一个线程完成了任务后,CountDownLatch的值就减1,当值为0的时候,代表所有线程完成 ...

  3. 线程同步工具CountDownLatch

    CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行.假如我们这个想要继续往下执行的任务调用一个CountDownLatc ...

  4. JUC并发工具类之 CountDownLatch等待多线程完成

    上篇JUC同步工具之Semaphore - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)示例中,资源释放一个线程就可以退出然后另一个线程可以使用了,那如果需要所有规定数量的资源同时释放了才 ...

  5. JUC常用同步工具类——CountDownLatch,CyclicBarrier,Semaphore

    在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 一.CountDownLa ...

  6. Java多线程同步工具类之CountDownLatch

    在过去我们实现多线程同步的代码中,往往使用join().wait().notiyAll()等线程间通信的方式,随着JUC包的不断的完善,java为我们提供了丰富同步工具类,官方也鼓励我们使用工具类来实 ...

  7. Java并发之CountDownLatch 多功能同步工具类

    package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * CountD ...

  8. java5 CountDownLatch同步工具

    好像倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当到达0时,所有等待者就开始执行. java.util.concurrent.CountDownLatch ...

  9. 并发是个什么鬼之同步工具类CountDownLatch

    扯淡 写这篇文章,我先酝酿一下,实不相瞒,脱离底层太久了,更确切的情况是,真没曾认真研究过.就目前来说,很多框架包括工具类已经把实现封装的很深,你只需轻轻的调用一下API,便不费半点力气.以至于大家会 ...

  10. 同步工具:CountDownLatch、CyclicBarrier和Semaphore

    1. CountDownLatch 1.1 功能及使用场景 一个同步工具,使得一个或多个线程等待一组线程执行完成后再执行. 使用场景:等待一些前置任务执行完成后,再执行特定的功能.比如,系统启动时,各 ...

随机推荐

  1. ARM体系与架构【一】

    由于笔试题(摩尔线程笔试题)也出现了相关的题目,所以也顺便为此做一点点小准备. 1.ARM用什么类型的指令集 ARM架构用的是RISC精简指令集. 2.RISV与RISC指令集有什么区别 3.ARM架 ...

  2. Halcon代码导出到.net FrameWork/WPF

    1. 应用背景 在工业项目中,往往需要使用机器视觉结合人机界面开发特定的,面向工艺的项目.机器视觉中,Halcon无疑是功能强大的,能快速应用到项目的视觉产品,而WPF则是解决人机界面的利器.因此了解 ...

  3. 在Vue的mixins(混入)里面调用Vuex(@/store/index.js)的函数

    第一步:在mixin.js里面引入 mapMutations 第二步:跟组件内调用一样,在methods里面写 "...mapMutations(['xxx'])",   然后LZ ...

  4. java锁之初相见

    废话不多说,先上锁的分类图 1.乐观锁&悲观锁 悲观锁 悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,把别的线程阻塞住,最终确保数据不会被别的线程修改. ...

  5. PHP 合并两个二维数组

    思路:遍历二维数组,合并两个二维数组的值,赋值给新数组 function mergeArray($arr1,$arr2){ $newArr = []; foreach($arr1 as $v1){ f ...

  6. Thinkpad键盘操作手册与驱动 thinkpad蓝牙键盘KT-1525 manual

    thinklife mechanical keyboard tk500_win10.exe https://pan.baidu.com/s/1pQM3RcgV-phugew6vcKDLw

  7. win10、win11安装子系统kali linux、图形化界面的安装

    1.开启安装Linux子系统需要的扩展 Win+Q搜索功能 勾选需要的扩展,Hyper-V.Windows 虚拟机监控平台.适用于Linux的Windows子系统.虚拟机平台 反正这些有关于虚拟机的全 ...

  8. PHP 循环语句

    循环机构,在一定的控制下,对此执行. 在PHP中,有以下几种循环 for循环.while循环.do-while循环.forech循环(针对数组) for 循环 语法 for (条件1;条件2;条件3) ...

  9. Android笔记--文本输入

    编辑框EditText 相关内部部件取下: inputType的类型如下: 具体实现: 不同边框的实现: 焦点变更监听器 具体实现: 文本变化监听器 具体实现:

  10. Python学习笔记--列表来啦!

    列表的定义格式 示例: 列表的下标索引(千万别超出范围!!!) 示例: 正向和反向 取出嵌套列表的元素:(二维数组) 列表的常用的操作方法 查找某元素的下标 示例: 修改元素 插入元素 示例: 追加元 ...