Java多线程同步工具类CountDownLatch详解

Java多线程同步工具类CountDownLatch详解

CountDownLatch是Java多线程中的一个同步工具类,它可以让一个或多个线程等待一组事件完成后再执行。

基本使用

CountDownLatch的基本使用场景是:在多个线程执行时,有一个或多个线程需要等待其他线程都完成任务后再继续执行。这时候可以使用CountDownLatch来实现。

在使用CountDownLatch时,首先需要创建CountDownLatch对象,设置计数器为需要等待的线程数量。当每个线程执行完任务后都会调用CountDownLatch对象的countDown()方法,将计数器减1。当计数器为0时,等待中的线程就会被唤醒,继续执行。

示例代码如下:

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        int threadNum = 3;
        CountDownLatch latch = new CountDownLatch(threadNum);

        for (int i = 0; i < threadNum; i++) {
            new Thread(() -> {
                try {
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName() + " 执行完毕");
                    latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }

        latch.await();
        System.out.println("所有线程执行完毕");
    }
}

在这个例子中,我们创建了一个计数器为3的CountDownLatch对象,表示等待3个线程执行完毕后再继续执行。

我们在for循环中创建了3个线程,每个线程执行完任务后都会调用latch.countDown()方法。最后我们调用latch.await()方法,等待所有线程执行完毕。当所有计数器都被减为0时,等待中的线程就会被唤醒,继续执行。最后输出“所有线程执行完毕”。

高级使用

除了基本使用场景外,CountDownLatch还可以用来解决更为复杂的问题。例如,我们需要等待多个线程完成不同的任务后再执行。这时候可以使用CountDownLatch的多次countDown()方法来实现。

示例代码如下:

public class CountDownLatchExample2 {
    public static void main(String[] args) throws InterruptedException {
        int taskNum = 3;
        CountDownLatch totalLatch = new CountDownLatch(taskNum);

        CountDownLatch task1Latch = new CountDownLatch(1);
        CountDownLatch task2Latch = new CountDownLatch(1);
        CountDownLatch task3Latch = new CountDownLatch(1);

        new Thread(() -> {
            try {
                task1();
                task1Latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            totalLatch.countDown();
        }).start();

        new Thread(() -> {
            try {
                task2();
                task2Latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            totalLatch.countDown();
        }).start();

        new Thread(() -> {
            try {
                task3();
                task3Latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            totalLatch.countDown();
        }).start();

        task1Latch.await();
        task2Latch.await();
        task3Latch.await();
        System.out.println("所有任务执行完毕");
    }

    private static void task1() throws InterruptedException {
        Thread.sleep(3000);
        System.out.println("任务1执行完毕");
    }

    private static void task2() throws InterruptedException {
        Thread.sleep(2000);
        System.out.println("任务2执行完毕");
    }

    private static void task3() throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("任务3执行完毕");
    }
}

在这个例子中,我们创建了一个计数器为3的CountDownLatch对象totalLatch,表示等待3个任务执行完毕后再继续执行。

我们还创建了3个单独的CountDownLatch对象task1Latch、task2Latch和task3Latch,用来分别等待任务1、任务2和任务3执行完毕。

我们创建了3个线程来执行这3个任务。当每个线程执行完任务后都会调用totalLatch.countDown()方法,将总的计数器减1。当所有任务执行完毕后,totalLatch计数器为0,等待中的线程就会被唤醒,继续执行。

最后我们等待每个任务的计数器都减为0(任务1、任务2和任务3分别对应task1Latch、task2Latch和task3Latch),然后输出“所有任务执行完毕”。

这是CountDownLatch的高级使用,可以灵活应用在各种多线程场景中。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程同步工具类CountDownLatch详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Log4j关闭Spring和Hibernate日志打印方式

    请注意,Log4j是一个Java类库,用于记录日志信息。它允许您控制应用程序日志记录输出的格式,位置和其他属性。 如果您使用Spring和Hibernate作为应用程序的框架,那么很有可能您需要禁用它们的日志记录;也就是说,当您运行应用程序时,您不希望在日志输出中看到Spring或Hibernate的消息。 下面是一些简单的步骤,可以帮助您关闭Spring和…

    Java 2023年5月20日
    00
  • Java源码刨析之ArrayQueue

    Java源码刨析之ArrayQueue攻略 前言 在这篇文章中,我们将深入探究Java中ArrayQueue的实现原理。ArrayQueue是一种基于数组实现的队列,它的特点是入队和出队的时间复杂度均为O(1),空间复杂度为O(n)。其实现原理对于Java初学者而言可能略显复杂,但理解了其原理就可以举一反三,掌握更多队列的实现方式。 代码分析 数据结构 Ar…

    Java 2023年5月26日
    00
  • Java的MyBatis框架中Mapper映射配置的使用及原理解析

    下面是针对“Java的MyBatis框架中Mapper映射配置的使用及原理解析”的完整攻略: 1. Mapper映射配置的基本概念 在MyBatis框架中,Mapper映射配置是用来描述Java对象和SQL语句之间映射关系的XML文件。通过配置Mapper,MyBatis可以根据SQL语句自动生成相应的Java代码。 一个Mapper的配置文件通常包括以下几…

    Java 2023年5月20日
    00
  • Java struts2 package元素配置及实例解析

    Java Struts2 package元素配置及实例解析 package元素是Struts2框架中用于定义一个组件的基本配置信息的容器,其包含很多子元素,用于设置组件的基本属性和行为。本文将详细介绍package元素的配置及实例解析,帮助读者更快速、准确地掌握Struts2框架的使用。 package元素配置 package元素是Struts2中配置文件中…

    Java 2023年5月20日
    00
  • java对象与json对象间的相互转换的方法

    Java对象与JSON对象之间相互转换的方法 在Java与前端的交互中,常常需要Java对象与JSON对象之间的相互转换。这里介绍两种常用的转换方法:使用Jackson和Gson库进行转换。 使用Jackson进行Java对象和JSON对象的相互转换 步骤一:引入Jackson库 在pom.xml中添加以下依赖: <dependency> &lt…

    Java 2023年5月26日
    00
  • SpringDataJpa多表操作的实现

    我来为你详细讲解“SpringDataJpa多表操作的实现”的完整攻略。下面是完整步骤: 环境要求 在开始之前,请确保已经安装了如下环境: JDK8+ Maven SpringBoot 2.x SpringData JPA 配置数据源 首先需要配置数据源,这里以MySQL为例。在application.properties中添加如下配置: spring.da…

    Java 2023年5月20日
    00
  • Sprint Boot @Validated使用方法详解

    Spring Boot的@Validated的作用与使用方法 在Spring Boot中,@Validated注解用于对方法参数进行校验。通过使用@Validated注解,可以确保方法参数满足特定的条件,从而提高应用程序的健壮性和可靠性。 @Validated注解的作用 @Validated注解用于对方法参数进行校验。当使用@Validated注解标记一个方…

    Java 2023年5月5日
    00
  • java安全编码指南之:Mutability可变性详解

    Java安全编码指南之:Mutability可变性详解 在Java编程中,可变性(Mutability)是一个非常重要的概念。可变性指的是对象在创建之后是否可被修改。如果一个对象是可变的,那么它的状态可以被修改,而不可变对象的状态则不能被修改。在Java编程中,一些安全漏洞与可变性有关,因此在编写Java代码时,我们需要特别注意可变性问题。 不可变对象的优点…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部