java并发编程JUC CountDownLatch线程同步

 更新时间:2021年09月02日 17:02:20   作者:字母哥博客  
这篇文章主要介绍CountDownLatch是什么、CountDownLatch 如何工作、CountDownLatch 的代码例子来展开对java并发编程JUC CountDownLatch线程同步,需要的朋友可以参考下面文章内容

java并发编程JUC CountDownLatch线程同步

CountDownLatch是一种线程同步辅助工具,它允许一个或多个线程等待其他线程正在执行的一组操作完成。CountDownLatch的概念在java并发编程中非常常见,面试也会经常被问到,所以一定要好好理解掌握。

CountDownLatch与其他并发编程工具类,如CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue等在java.util.concurrent包中与JDK 1.5一起被引入。CountDownLatch能让一个java线程等待其他线程完成任务,比如Application的主线程等待,直到其他负责启动框架服务的服务线程完成所有服务的启动。

1、CountDownLatch是什么?

CountDownLatch用线程数来初始化一个计数器,每当一个线程完成执行时,这个计数器就会递减。当计数为零时,表示所有线程都已完成执行,处于等待状态的主线程可以继续执行。

下面我们使用伪代码的方式描述CountDownLatch 的作用

  • 主线程启动,并为N个线程(假设n=3)初始化CountDownLatch(n)
  • 启动n个线程
  • 主线程阻塞等待
  • 线程1执行完成,CountDownLatch -1 = 2,主线程继续阻塞
  • 线程3执行完成,CountDownLatch -1 = 1,主线程继续阻塞
  • 线程4执行完成,CountDownLatch -1 = 0,主线程恢复执行

2、CountDownLatch 如何工作

CountDownLatch.java类里面定义了一个构造函数。count实质上是线程数,这个值只能设置一次,CountDownLatch没有提供方法来重置这个数

CountDownLatch.public CountDownLatch(int count) {...}

使用CountDownLatch的主线程要去等待其他线程执行完成,所以这个主线程必须在启动其他线程后立即调用 CountDownLatch.await() 方法,该方法阻塞主线程处于等待状态,直到其他线程执行完毕,才会停止阻塞。

其他N个线程必须有CountDownLatch对象的引用,因为它们需要通知CountDownLatch对象它们已经完成任务。这个通知是由方法CountDownLatch.countDown()来完成的,每调用一次该方法,就会将构造函数中设置的初始计数count减少1,所以当所有N个线程都调用了这个方法后count计数达到0,主线程就可以不受await()方法阻塞恢复执行了。

所以CountDownLatch特别适合于那些需要等待N个线程完成后再开始执行的场景。例如一个应用程序的启动类,在处理用户请求之前,要确保所有N个外部系统都是处于运行状态的。

3、CountDownLatch 代码例子

假设我们的应用程序主线程启动之前,要检查另外4个程序是否准备就绪,只有其他的4个程序准备就绪,我们的主程序才能继续执行。就可以使用下面的代码来操作:

import java.util.concurrent.CountDownLatch;

public class Tester {
   public static void main(String args[]) {
      //设置计数器 counter = 4 ,等于线程数
      CountDownLatch countDownLatch = new CountDownLatch(4);

      Thread app1 = new Thread(new Application("App1",  countDownLatch));
      Thread app2 = new Thread(new Application("App2",  countDownLatch));          
      Thread app3 = new Thread(new Application("App3",  countDownLatch));
      Thread app4 = new Thread(new Application("App4",  countDownLatch));  
 
      // 启动多线程去检查其他四个程序的可用状态
      app1.start();
      app2.start();
      app3.start();
      app4.start();

      try {
         //主线程调用await进行等待,等待上述四个线程正常完成
         countDownLatch.await();            
         //上述四个线程检查的应用程序启动正常之后, 打印如下信息
         System.out.println("All applications are up and running.");
      } catch(InterruptedException e) {
         System.out.println(e.getMessage());
      }        
   }
}

子线程程序,每一个线程都持有countDownLatch对象,线程正常执行完成之时,使用countDownLatch.countDown()方法将countDownLatch对象的计数器减1。

class Application implements Runnable {
   private String name; //应用程序名称
   private CountDownLatch countDownLatch; 

   public Application(String name, CountDownLatch countDownLatch) {
      this.name = name;
      this.countDownLatch = countDownLatch;
   }

   public void run() {
      try {
         System.out.println(name + " started. ");
         Thread.sleep(1000);
      } catch (InterruptedException e) {
         System.out.println(e.getMessage());
      }
      System.out.println( name + " is Up and running.");
      //将countDownLatch计数器的值减1
      countDownLatch.countDown();    
   }
}

上述程序的打印输出结果是,可以结合输出结果去理解上文中讲述的CountDownLatch 工作原理:

App2 started.  
App3 started.  
App1 started.  
App4 started.  
App1 is Up and running.
App3 is Up and running.
App4 is Up and running.
App2 is Up and running.
All applications are up and running.

到此这篇关于java并发编程JUC CountDownLatch线程同步的文章就介绍到这了,更多相关java JUC CountDownLatch线程同步内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring注解和同步锁不能同步问题解决

    Spring注解和同步锁不能同步问题解决

    这篇文章主要介绍了Spring注解和同步锁不能同步问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Java While循环 do-while循环用法

    Java While循环 do-while循环用法

    循环语句就是让计算机根据条件做循环计算,在条件满足时继续循环,条件不满足时退出循环,需要的朋友可以参考下
    2020-11-11
  • 从java反编译及字节码角度探索分析String拼接字符串效率

    从java反编译及字节码角度探索分析String拼接字符串效率

    这篇文章主要介绍了从java反编译及字节码角度探索分析String拼接字符串效率,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • java中@JSONField和@JsonProperty注解的使用说明及对比

    java中@JSONField和@JsonProperty注解的使用说明及对比

    @JSONField与@JsonProperty隶属两个不同的包,前者是阿里系的fastjson包,后者是spring boot官方使用的jackson包,本文主要介绍了java中@JSONField和@JsonProperty注解的使用说明及对比,感兴趣的可以了解一下
    2023-11-11
  • 在maven中引入本地jar包的步骤

    在maven中引入本地jar包的步骤

    这篇文章主要介绍了在maven中引入本地jar包的步骤,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-04-04
  • Java程序员应该遵守的10条纪律

    Java程序员应该遵守的10条纪律

    Java程序员有许多应遵循的守则或最佳实践方式。本文概述了每个开发者最应该遵循的10条守则或戒律,如果不遵循它们,将会导致灾难性后果。
    2015-09-09
  • SpringBoot多环境切换的配置实现

    SpringBoot多环境切换的配置实现

    在日常的开发中,一般都会分好几种环境,本文就来介绍一下SpringBoot多环境切换的配置实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Java如何自定义类数组的创建和初始化

    Java如何自定义类数组的创建和初始化

    这篇文章主要介绍了Java如何自定义类数组的创建和初始化,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Mybatis中拦截器的简单实现方法

    Mybatis中拦截器的简单实现方法

    这篇文章主要给大家介绍了关于Mybatis中拦截器的简单实现方法,文中通过示例代码介绍的非常详细,对大家学习或者使用Mybatis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-08-08
  • java使用httpclient模拟post请求和get请求示例

    java使用httpclient模拟post请求和get请求示例

    这篇文章主要介绍了java使用httpclient模拟post请求和get请求示例,需要的朋友可以参考下
    2014-02-02

最新评论