首页 Java java教程 Java中CountDownLatch进行多线程同步的示例代码分享

Java中CountDownLatch进行多线程同步的示例代码分享

Mar 21, 2017 am 10:27 AM

这篇文章主要介绍了Java中CountDownLatch进行多线程同步详解及实例代码的相关资料,需要的朋友可以参考下

Java中CountDownLatch进行多线程同步详解

CountDownLatch介绍

在前面的Java学习笔记中,总结了Java中进行多线程同步的几个方法:

1、synchronized关键字进行同步。
2、Lock锁接口及其实现类ReentrantLock、ReadWriteLock锁实现同步。
3、信号量Semaphore实现同步。

其中,synchronized关键字和Lock锁解决的是多个线程对同一资源的并发访问问题。信号量Semaphore解决的是多副本资源的共享访问问题。

今天,来学习一下Java中的另外一个多线程同步辅助类:CountDownLatch。官方文档对CountDownLatch的解释是:在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。也就是说,CountDownLatch控制某个或者多个线程,让它们等待多个线程完成某项任务后,再启动。CountDownLatch主要是用来同步多个任务的执行,区别于其他的synchronized关键字,锁,信号量是用来同步共享资源的。

CountDownLatch实现原理简介:

CountDownLatch内部维护一个计数器,计数器的值为待完成的任务数N,需要等待这N个任务完成的线程调用

CountDownLatch的await()方法使自己进入休眠等待状态。

当某一个任务线程完成某一个任务后调用CountDownLatch的countDown()方法来表示自己的任务已完成,此时CountDownLatch的计数器值减1,当所有的任务完成式,计数器的值为0。当计数器值为0时,CountDownLatch将唤醒所有因await()方法进入休眠的线程。

CountDownLatch的使用:

CountDownLatch的使用主要有3点:

1、CountDownLatch的声明及初始化,在初始化时需要指定等待完成的任务数。

2、某一个任务完成时调用CountDownLatch的countDown()方法,向CountDownLatch报告自己的任务已经完成,

3、需要等待任务完成的线程调用CountDownLatch的await()方法,调用后该线程将进入休眠,并在所有任务数完成后CountDownLatch的计数器值为0时,因await()方法进行休眠的线程将被唤醒。

在此本人在Java 7并发编程实战手册该书中的CountDownLatch使用示例的基础上做了部分改进,来演示CountDownLatch的使用详情:

模拟10个参会者和一个主持人参加的一个会以,每个参会者及主持人需要等待其他的参会者均到场签到之后,才能开始会以并发言。为此,先创建一个会以管理的类VideoConference,其提供一个arrive()方法供参会者调用来进行签到。会议管理的拥有者是主持人,其等待每个参会者的签到:

public class VideoConference implements Runnable{ 
  private final CountDownLatch countDownLatch; 
  private int number; 
  public VideoConference(int number) { 
    this.number = number; 
    this.countDownLatch = new CountDownLatch(number);//使用Number初始化其内部的计数器,当初始化完成后,不能再次初始化 
  } 
  public void arrive(String name){ 
    //每个需要同步的任务,在任务完成时,需要调用该方法 
    countDownLatch.countDown();//countDownLatch内部的计数器减1 
    System.out.print("arrive:"+name+"\n"); 
    try{ 
      countDownLatch.await();//await方法是线程进入休眠,当countDownLatch计数器为0时,将被唤醒 
      //线程被唤醒,在这里可以执行一系列任务 
      System.out.print("name:"+name + " say:let's start..." +"\n"); 
    }catch (InterruptedException e){ 
      e.printStackTrace(); 
    } 
  } 
  public void run(){ 
    System.out.print("has arrive:"+(number-countDownLatch.getCount())+"\n"); 
    try{ 
      countDownLatch.await();//await方法是线程进入休眠,当countDownLatch计数器为0时,将被唤醒 
      //线程被唤醒,在这里可以执行一系列任务 
      System.out.print("all arrived:"+(number-countDownLatch.getCount())+"\n"); 
    }catch (InterruptedException e){ 
      e.printStackTrace(); 
    } 
  } 
}
登录后复制

创建一个参会者类Participant:

public class Participant implements Runnable{ 
  private VideoConference videoConference; 
  private String name; 
 
  public Participant(String name, VideoConference videoConference) { 
    this.name = name; 
    this.videoConference = videoConference; 
  } 
  public void run(){ 
    try { 
      //do something 
      Thread.sleep(50); 
      // 
      videoConference.arrive(name); 
    }catch (InterruptedException e){ 
      e.printStackTrace(); 
    } 
  } 
 
  public static void main(String[] args){ 
    VideoConference videoConference = new VideoConference(10); 
    Thread videoThread = new Thread(videoConference); 
    videoThread.start(); 
    for(int i=0; i<10; i++){ 
      Thread thread = new Thread(new Participant("participant:"+i,videoConference)); 
      thread.start(); 
    } 
  } 
}
登录后复制

Participant类中的main函数首先创建了一个需要10个参会者参加的一个会议,之后,创建了10个参会者并逐个签到,在10个参会者都签到之后,每个参会者及主持人将被"唤醒"并发言。

总结:

CountDownLatch类解决的是多线程间的同步等待、任务协调问题,应用在如在启动某个程序的主功能前,需要前置完成配置环境检查、网络检查等多个子任务等类似的场景。在Java中,除了使用CountDownLatch来实现多线程间的同步等待以外,还可以使用栅栏技术CyclicBarrier来实现多线程间的同步等待、任务协调。

以上是Java中CountDownLatch进行多线程同步的示例代码分享的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Java 中的平方根 Java 中的平方根 Aug 30, 2024 pm 04:26 PM

Java 中的平方根指南。下面我们分别通过例子和代码实现来讨论平方根在Java中的工作原理。

Java 中的完美数 Java 中的完美数 Aug 30, 2024 pm 04:28 PM

Java 完美数指南。这里我们讨论定义,如何在 Java 中检查完美数?,示例和代码实现。

Java 中的阿姆斯特朗数 Java 中的阿姆斯特朗数 Aug 30, 2024 pm 04:26 PM

Java 中的阿姆斯特朗数指南。这里我们讨论一下java中阿姆斯特朗数的介绍以及一些代码。

Java 中的随机数生成器 Java 中的随机数生成器 Aug 30, 2024 pm 04:27 PM

Java 随机数生成器指南。在这里,我们通过示例讨论 Java 中的函数,并通过示例讨论两个不同的生成器。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。这里我们通过示例讨论简介、如何使用weka java、平台类型和优点。

Java 中的史密斯数 Java 中的史密斯数 Aug 30, 2024 pm 04:28 PM

Java 史密斯数指南。这里我们讨论定义,如何在Java中检查史密斯号?带有代码实现的示例。

Java Spring 面试题 Java Spring 面试题 Aug 30, 2024 pm 04:29 PM

在本文中,我们保留了最常被问到的 Java Spring 面试问题及其详细答案。这样你就可以顺利通过面试。

突破或从Java 8流返回? 突破或从Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

See all articles