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

yizhihongxing

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日

相关文章

  • java实现简单的ATM项目

    Java实现简单的ATM项目攻略 1. 确定项目需求 在开发ATM项目之前,我们需要明确项目的需求以及功能,以便为项目建立蓝图。 1.1 项目需求 用户登录,包括账户名和密码验证 存款和取款 查询余额 修改密码 银行卡挂失/解挂 退出系统 1.2 功能 用户登录:用户需要输入账号和密码进行登录。 存款和取款:用户可以选择存款或取款操作并输入具体金额。 查询余…

    Java 2023年5月19日
    00
  • mysql+spring+mybatis实现数据库读写分离的代码配置

    MySQL数据库读写分离是提高Web应用性能和可用性的重要手段之一。开发人员可以通过使用JDBC、Spring和MyBatis等技术实现MySQL数据库读写分离。 以下是实现数据库读写分离的完整攻略: 1. 安装和配置MySQL主从服务器 确保安装和配置了MySQL主从服务器,并确保主服务器和从服务器之间已正确配置了“主从同步”。可以考虑使用软件程序如MyS…

    Java 2023年6月1日
    00
  • 关于Java中使用jdbc连接数据库中文出现乱码的问题

    关于Java中使用JDBC连接数据库中文出现乱码的问题,一般来说是由于编码不一致导致的。下面给出完整的攻略: 问题背景 当我们使用 Java 语言中所提供的 JDBC API 连接数据库时,如果发现 MySQL 数据库中存储的中文字符在程序中被读取后出现了乱码,那么这个问题就需要解决了。 解决方法 1. 在连接字符串中指定编码字符集 实现这个方法,需要在 J…

    Java 2023年5月20日
    00
  • java String到底有多长?String超出长度该如何解决

    Java中的String类型是一种特殊的引用类型,用于表示字符串。在Java中,字符串是不可变的,也就是说一旦创建就不能再修改了,所以内存中的字符串是一个长度固定的字符数组,但是这个长度是不确定的。 Java中的String类型的长度并不是固定的,而是动态分配的,具体大小取决于String对象中存储的字符数量。当创建一个新的String对象时,Java会根据…

    Java 2023年5月27日
    00
  • java多线程模拟交通灯管理系统

    下面我将详细讲解如何编写一个Java多线程模拟交通灯管理系统。 前言 交通灯是城市中必不可少的重要设施之一,能帮助路面交通管理变得更加有序。为了更好地理解交通灯的工作原理,我们可以开发一个Java多线程模拟交通灯管理系统来模拟交通灯的运行过程。 设计思路 我们的系统需要设计两个交通灯对象,即红绿灯和绿红灯,交替更替地工作。为了实现此目的,我们可以使用多线程的…

    Java 2023年5月19日
    00
  • SpringMVC集成Web与MVC执行流程和数据响应及交互相关介绍全面总结

    以下是关于“SpringMVC集成Web与MVC执行流程和数据响应及交互相关介绍全面总结”的完整攻略,其中包含两个示例。 SpringMVC集成Web与MVC执行流程和数据响应及交互相关介绍全面总结 SpringMVC是一个基于MVC模式的Web框架,它提供了一种灵活、高效的方式来开发Web应用程序。在SpringMVC中,Web和MVC是如何集成的?Spr…

    Java 2023年5月16日
    00
  • Java实现解析dcm医学影像文件并提取文件信息的方法示例

    Sure! 首先需要明确的是,“dcm医学影像文件”是DICOM格式的医学影像文件,其中包含了病人的医学影像信息。其次,Java解析DICOM文件需要用到专门的库,常用的有dcm4che和ImageJ等。 下面是Java实现解析dcm医学影像文件并提取文件信息的步骤和示例: 准备工作 下载dcm4che库(https://sourceforge.net/pr…

    Java 2023年5月20日
    00
  • springboot与redis的简单整合实例

    在Spring Boot应用程序中,我们可以使用Redis来实现缓存和数据存储。以下是实现Spring Boot与Redis的简单整合实例的完整攻略: 添加依赖 在Spring Boot应用程序中,我们需要添加以下依赖来使用Redis: <dependency> <groupId>org.springframework.boot&lt…

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