当前位置: 首页 > 知识库问答 >
问题:

倒计时锁在Java多线程中是如何使用的?

司徒英卓
2023-03-14

有人能帮我理解什么是JavaCountDownLatch以及什么时候使用它吗?

我不太清楚这个程序是如何工作的。据我所知,所有三个线程都同时启动,每个线程在3000ms后都会调用CountDownLatch。所以倒计时会一个接一个地递减。闩锁变为零后,程序会打印“已完成”。也许我理解的方式不正确。

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class Processor implements Runnable {
    private CountDownLatch latch;

    public Processor(CountDownLatch latch) {
        this.latch = latch;
    }

    public void run() {
        System.out.println("Started.");

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        latch.countDown();
    }
}

// -----------------------------------------------------

public class App {

    public static void main(String[] args) {

        CountDownLatch latch = new CountDownLatch(3); // coundown from 3 to 0

        ExecutorService executor = Executors.newFixedThreadPool(3); // 3 Threads in pool

        for(int i=0; i < 3; i++) {
            executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
        }

        try {
            latch.await();  // wait until latch counted down to 0
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Completed.");
    }

}

共有3个答案

邴兴为
2023-03-14

NikolaB解释得很好,但是例子会有助于理解,所以这里有一个简单的例子...

 import java.util.concurrent.*;


  public class CountDownLatchExample {

  public static class ProcessThread implements Runnable {

    CountDownLatch latch;
    long workDuration;
    String name;

    public ProcessThread(String name, CountDownLatch latch, long duration){
        this.name= name;
        this.latch = latch;
        this.workDuration = duration;
    }


    public void run() {
        try {
            System.out.println(name +" Processing Something for "+ workDuration/1000 + " Seconds");
            Thread.sleep(workDuration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(name+ "completed its works");
        //when task finished.. count down the latch count...

        // basically this is same as calling lock object notify(), and object here is latch
        latch.countDown();
    }
}


public static void main(String[] args) {
    // Parent thread creating a latch object
    CountDownLatch latch = new CountDownLatch(3);

    new Thread(new ProcessThread("Worker1",latch, 2000)).start(); // time in millis.. 2 secs
    new Thread(new ProcessThread("Worker2",latch, 6000)).start();//6 secs
    new Thread(new ProcessThread("Worker3",latch, 4000)).start();//4 secs


    System.out.println("waiting for Children processes to complete....");
    try {
        //current thread will get notified if all chidren's are done 
        // and thread will resume from wait() mode.
        latch.await();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

    System.out.println("All Process Completed....");

    System.out.println("Parent Thread Resuming work....");



     }
  }
李意致
2023-03-14

Java中的CountDownLatch是一种同步器,它允许一个线程在开始处理之前等待一个或多个线程s。

CountDownLatch根据锁存原理工作,线程将等待门打开。一个线程等待n创建CountDownLatch时指定的线程数。

例如最终CountDownLatch闩锁=new CountDownLatch(3);

这里我们把计数器设为3。

任何线程,通常是应用程序的主线程,调用countdownlock。wait()将等待计数达到零或被另一个线程中断。所有其他线程都需要通过调用CountDownLatch进行倒计时。工作完成后,他们就可以开始倒计时了。当计数达到零时,线程等待开始运行。

这里的计数通过CountDownLatch递减。倒计时()方法。

调用await()方法的线程将等待初始计数达到零。

要使计数为零,其他线程需要调用CountDown()方法。一旦计数为零,调用wait()方法的线程将恢复(开始执行)。

CountDownLatch的缺点是它不可重用:一旦计数为零,它就不再可用。

方河
2023-03-14

是的,你没理解错。CountDownLatch在闩锁原理下工作,主线程将等到门打开。一个线程等待n个线程,在创建CountDownLatch时指定。

任何线程,通常是应用程序的主线程,调用CountDownLatch.await()都会等待,直到计数达到零或者被另一个线程中断。所有其他线程都需要在完成或准备好后通过调用CountDownLatch.countDown()进行倒计时。

一旦计数达到零,等待线程就会继续。CountDownLatch的缺点/优点之一是它不能重用:一旦计数达到零,您就不能再使用CountDownLatch

编辑:

当一个线程(如主线程)需要等待一个或多个线程完成后才能继续处理时,请使用CountDownLatch

在Java中使用CountDownLatch的一个经典示例是一个服务器端核心Java应用程序,它使用服务体系结构,其中多个线程提供多个服务,在所有服务成功启动之前,应用程序无法启动处理。

P.S.OP的问题有一个非常简单的例子,所以我没有包括一个。

 类似资料:
  • 我正在学习Java中的同步。我无法理解倒计时锁的确切机制。 CountDownLatch是否根据声明中给出的线程数“倒数锁存器”(等待线程数完成)? 这是我试图理解的代码: 在上面的例子中: ExecutorService(从线程池)生成7个线程。我的理解是闩锁应该等待6个线程(从0到5)的完成,定义如下: 但我得到的输出并不是每次都是恒定的。有时会等待6个线程完成,有时会等待7个线程完成,例如:

  • 本文向大家介绍Android 中不用线程如何实现倒计时,包括了Android 中不用线程如何实现倒计时的使用技巧和注意事项,需要的朋友参考一下 需求: 有多个组件可以开启倒计时,正常情况下默认倒计时时间终了后更新UI,另,用户可以取消指定倒计时。 这里使用CountDownTimer进行倒计时,其中回调函数onFinish是在倒计时终了时回调,onTick是在倒计时开始时回调,用户可以使用Coun

  • 问题内容: 有人可以帮助我了解什么是Java 以及何时使用它吗? 对于该程序的工作方式,我没有一个很清楚的想法。据我了解,所有三个线程同时启动,每个线程将在3000ms之后调用CountDownLatch。因此,递减计数将逐一递减。锁存器变为零后,程序将打印“ Completed”。也许我的理解方式不正确。 // ------------------------------------------

  • 问题内容: 我需要直接等于的东西,但可以重置(保持线程安全!)。我不能使用经典的同步构造,因为它们在这种情况下根本无法工作(复杂的锁定问题)。目前,我正在创建许多对象,每个对象都替代了上一个对象。我相信这是在GC的年轻一代中实现的(由于对象数量众多)。您可以在下面看到使用闩锁的代码(这是ns-3网络模拟器接口模拟的一部分)。 有些想法可能是尝试(JDK5 +)或(JDK7) 我可以测试代码,然后回

  • 问题内容: 我想知道是否有人可以帮助我。经过数小时的不懈搜索,在这里和网上我似乎找不到使用jquery的简单倒计时。我不想使用任何类型的插件,而只是简单的jquery代码来从日期倒数。我设法在下面找到此代码。但是即使将此代码放置在我的网站中,也不会显示任何内容。我从jquery.com添加了jquery文件,并添加了ID不包含任何内容的正确div 。如果有人可以解释或告诉我如何在采用日期格式并返回

  • 问题内容: 如何使用Swift 进行倒数计时? 问题答案: 问题1: 问题2: 两者都可以。SpriteKit是用于场景,运动等的SDK。简单视图应用程序是项目模板。他们不应该冲突