JUC同步工具CountDownLatch
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的更多相关文章
- Java并发和多线程4:使用通用同步工具CountDownLatch实现线程等待
CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 用给定的计数 初始化 CountDownLatch.由于调用了 countDown ...
- Java多线程_同步工具CountDownLatch
概念:CountDownLatch是多线程里面一个类似于计数器的高级同步工具,它的初始值代表线程的数量,当一个线程完成了任务后,CountDownLatch的值就减1,当值为0的时候,代表所有线程完成 ...
- 线程同步工具CountDownLatch
CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行.假如我们这个想要继续往下执行的任务调用一个CountDownLatc ...
- JUC并发工具类之 CountDownLatch等待多线程完成
上篇JUC同步工具之Semaphore - 池塘里洗澡的鸭子 - 博客园 (cnblogs.com)示例中,资源释放一个线程就可以退出然后另一个线程可以使用了,那如果需要所有规定数量的资源同时释放了才 ...
- JUC常用同步工具类——CountDownLatch,CyclicBarrier,Semaphore
在 JUC 下包含了一些常用的同步工具类,今天就来详细介绍一下,CountDownLatch,CyclicBarrier,Semaphore 的使用方法以及它们之间的区别. 一.CountDownLa ...
- Java多线程同步工具类之CountDownLatch
在过去我们实现多线程同步的代码中,往往使用join().wait().notiyAll()等线程间通信的方式,随着JUC包的不断的完善,java为我们提供了丰富同步工具类,官方也鼓励我们使用工具类来实 ...
- Java并发之CountDownLatch 多功能同步工具类
package com.thread.test.thread; import java.util.Random; import java.util.concurrent.*; /** * CountD ...
- java5 CountDownLatch同步工具
好像倒计时计数器,调用CountDownLatch对象的countDown方法就将计数器减1,当到达0时,所有等待者就开始执行. java.util.concurrent.CountDownLatch ...
- 并发是个什么鬼之同步工具类CountDownLatch
扯淡 写这篇文章,我先酝酿一下,实不相瞒,脱离底层太久了,更确切的情况是,真没曾认真研究过.就目前来说,很多框架包括工具类已经把实现封装的很深,你只需轻轻的调用一下API,便不费半点力气.以至于大家会 ...
- 同步工具:CountDownLatch、CyclicBarrier和Semaphore
1. CountDownLatch 1.1 功能及使用场景 一个同步工具,使得一个或多个线程等待一组线程执行完成后再执行. 使用场景:等待一些前置任务执行完成后,再执行特定的功能.比如,系统启动时,各 ...
随机推荐
- MariaDB简介
一.什么是数据库 DB 与 DBMS :DB(DataBase)即数据库,存储已经组织好的数据的容器.DBMS(DataBase Manage System)是数据库管理系统用来对数据库及数据库中的数 ...
- .net Core5.0使用IdentityServer4 进行权限控制
.net Core5.0使用IdentityServer4 进行权限控制 IdentityServer4 ASP.NET Core的一个包含OpenID Connect和OAuth 2.0协议的框架 ...
- Oracle Fusion Middleware Introduction
Oracle Fusion Middleware Oracle Fusion Middleware is a comprehensive family of software products tha ...
- C#向其实进程子窗体发送指令
近日,想在自己的软件简单控制其它软件的最大化最小化,想到直接向进程发送指令,结果一直无效,经过Spy++发现,原来快捷方式在子窗体上,所以需要遍历子窗体在发送指令,以下为参考代码: 1 [DllImp ...
- NX二次开发获取NX主程序路径
//头文件 #include <Windows.h> #include <iostream> #include <NXOpen/ListingWindow.hxx> ...
- iview 中Modal组件点击确定后验证信息不通过则不关闭弹窗方法
<Modal v-model="isTemManageShow" title="管理模板" @on-ok="ok" :loading= ...
- 定制centos发行版
//轻量级Centos定制发行版==================================================================================== ...
- RK3399编译——基于nanoPC-T4
开发环境搭建 安装依赖 sudo apt install -y bison g++-multilib git gperf libxml2-utils make python-networkx zip ...
- 一个关于 Linux环境下输出操作符 >和>>的问题
[>和>>的区别]命令>文件,表示以覆盖的方式,把命令正确输出到指定的文件或者设备当中:命令>>文件,表示以追加的方式,把命令正确输出到指定的文件或者设备当中. [ ...
- Qt 学习笔记 - 第三章 - Qt的三驾马车之一 - 串口编程 + 程序打包成Windows软件
Qt 学习笔记全系列传送门: Qt 学习笔记 - 第一章 - 快速开始.信号与槽 Qt 学习笔记 - 第二章 - 添加图片.布局.界面切换 [本章]Qt 学习笔记 - 第三章 - Qt的三驾马车之一 ...