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 功能及使用场景 一个同步工具,使得一个或多个线程等待一组线程执行完成后再执行. 使用场景:等待一些前置任务执行完成后,再执行特定的功能.比如,系统启动时,各 ...
随机推荐
- APK 跳转其他APK
+import android.content.ComponentName;^M /* @@ -343,6 +346,15 @@ public class MainActivity extends A ...
- supervisor 使用中遇到的问题
supervisor 配置完毕,使用supervisorctl reload 和supervisorctl update 启动时候报错 解决方法使用下面命令启动 /usr/bin/python2 /u ...
- Python第十章实验报告
一.实验对象:<零基础学Python>6道实例和2道实战 二.实验环境:IDLE Shell 3.9.7 三.实验目的:学习如何在Python中进行文件和目录的相关操作 四.实验过程: 实 ...
- 1--我们写了一个java类,那么生成一个对象占用多大的内存?
public class Student { private long id; private long userId; private byte state; private long create ...
- Java 面试手撕代码
1. 判断括号有效性 public static boolean fun5(String str) { HashMap<Character, Character> hashMap = ne ...
- 如何利用Apifox通过签名计算及数据加解密进行用户认证接口测试?
用户注册场景:输入签名数据signature,appId,13位时间戳timestamp,6位随机数nonce,merchantId(非必填,本次不填)的请求参数发送给服务器,服务器返回响应数值后,校 ...
- 👋 和我一起学【Three.js】「初级篇」:0. 总论
「和我一起学 XXX」是我 2023 年的一个新企划,目的是向读者(也包括未来的自己)介绍我正在学习的某项新技术.文章会通过长期反复迭代的方式保持其内容的新鲜度.文章有较大内容更新时,会在文章开头进行 ...
- RPA主流厂商有哪些?
RPA(机器人流程自动化(Robotic Process Automation)是一种能够自动化基于规则.结构化和重复的业务流程的技术.机器人流程自动化降低了成本,同时防止了人为错误,该技术目前已应用 ...
- 写.jsp项目有感
本次练习了一个简单的登录界面 我觉得在写这种类型的界面的时候,需要将各个需求分开,就以这次的登录界面为例展开说说 1.登录界面 输入框的居中问题.登录按钮的跳转问题.验证码图片的随机问题.快速注册的跳 ...
- Day05笔记
01.数组类(了解) 1.目的:设计一个类,该类有数组的功能,可以存储数据,可以删除修改数据 2.设计核心数据 1.属性:指针(指向堆区空间),数组实际存储的元素个数,数组容量 2.方法:构造(开辟堆 ...