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. Ubuntu与centos之间的文件传输

          Ubuntu与centos之间的文件传输 默认端口:22 传输前确认端口是否开启 1.在Ubuntu上安装scp命令 apt-get install openssh-server 2.将U ...

  2. nodejs <a>带参数返回路由标记执行数据库操作

    今天在测试mongo数据库操作维护的时候,测试了一下直接在表内添加操作列来完成数据的删除操作,直接返回数据库ID,页面表格如下: 通过点击删除,即可完成对应条目数据库删除操作. 1.mongo数据操作 ...

  3. 新的世界,我们推荐不劳而获 -> 持续更新中

    随着技术带来的生产力爆发越来越猛烈,有人提出是不是有必要保留一些落后的生产工艺及相关岗位,以避免社会动荡. 我的答案:不用.但是要改变社会对于不劳而获的态度:我们对于生活资料的不劳而获持接受的态度,但 ...

  4. django orm的增删改查 以及django1.x和2.x的区别

    ORM对字段的增删改查 # 建一个作者表 class Author(models.Model): ''' 如果你以后在创建表的时候,主键就叫id名,那么可以省略不写,orm会自动帮你创建出主键名称为i ...

  5. ios装包

    一.下载爱思助手 二.找到本机设备 注:如果未弹出允许.拒绝调试选项可尝试换根数据线解决 三.将对应包体文件拖入本机设备

  6. Linux高并发服务器之Linux多线程开发

    本文源自C++高薪面试项目的学习笔记,主要记录Liunx多线程的学习,主要知识点是线程概述等基础概念以外,还有线程相关Liunx系统函数以及对应练手代码,除此之外还有线程同步问题的讲解以及实战多线程买 ...

  7. MySql生成ER【StarUML】文件

    1. 背景 要画ER图,一个个打费时费力,StarUML文件打开是json.那么就有可能自动生成. 2. 效果 把表结构生成好,自己只要维护关系即可. 3. 代码 import lombok.Data ...

  8. 【转载】谈谈GIS三维渲染引擎

    > 原文地址:https://zhuanlan.zhihu.com/p/419667971 三维引擎 minemap: 是我们公司的产品,主要以earth的形态展示,支持矢量切片+倾斜数据(这一 ...

  9. JVM 问题排查工具

    更多内容,前往 IT-BLOG Java 开发人员肯定都知道 JDK的 bin 目录中有 "java.exe"."javac.exe" 这两个命令行工具.下面主 ...

  10. deepin安装retropie

    deepin安装retropie,并解决游戏列表中文乱码已经retroarch中文乱码. 安装retropie模拟器 sudo apt install -y git dialog unzip xmls ...