Java多线程CountDownLatch的实现

yizhihongxing

下面是我对于“Java多线程CountDownLatch的实现”的完整攻略。

CountDownLatch简介

CountDownLatch是JavaSE5中并发包(java.util.concurrent)中的一个类,它可以允许一个线程等待一组线程完成操作后再继续执行。

具体来说,CountDownLatch 常用于某个线程需要等待其它线程执行完毕某些操作后再执行。你可以通过在 CountDownLatch 中指定线程的数量,从而实现让等待线程等待这些线程完成。

CountDownLatch 有两个重要方法:
- countDown():将 CountDownLatch 的数量减 1。
- await():让当前线程等待 CountDownLatch 中的数量变为 0。

CountDownLatch实现方式

下面我们通过一个简单的例子来演示如何使用 CountDownLatch。 在这个例子中,我们将创建一个主线程和三个子线程,主线程将等待这三个子线程完成任务后再唤醒继续执行。

import java.util.concurrent.CountDownLatch;
public class Example {
    public static void main(String[] args) throws InterruptedException {
        int count = 3;
        CountDownLatch latch = new CountDownLatch(count);
        for (int i = 0; i < count; i++) {
            Thread thread = new Thread(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + " 结束");
                latch.countDown();
            });
            thread.start();
        }
        System.out.println("等待子线程结束");
        latch.await();
        System.out.println("所有子线程都结束,主线程继续执行");
    }
}

运行上面的代码,你将得到以下输出:

等待子线程结束
Thread-0 结束
Thread-2 结束
Thread-1 结束
所有子线程都结束,主线程继续执行

在上述代码中,我们先创建了一个 CountDownLatch 类型的对象,并将它的计数器初始化为 3。然后我们创建了三个子线程,在每个子线程中模拟完成一个耗时任务(这里我们使用 Thread.sleep 模拟),最后调用 countDown() 方法让计数器减 1。然后在主线程中,我们使用 await() 方法来让主线程阻塞直到 CountDownLatch 中的计数器为 0 。这样主线程才能正常执行前面被阻塞的代码。

下面给出另一个例子,这里我们将使用 CountDownLatch 模拟三个线程协同工作的过程。在这个例子中,我们将随机生成一个数量为 30 的数组,然后让三个线程分别对这个数组的内容进行排序操作。最后我们再将这三个排序后的数组进行归并操作。

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
public class Example {
    public static void main(String[] args) throws InterruptedException {
        int count = 3;
        CountDownLatch latch = new CountDownLatch(count);
        int[] arr = generateArray(30); // 生成要排序的数组

        int[][] sortedArrs = new int[count][]; // 保存排序后的数组
        for (int i = 0; i < count; i++) {
            final int index = i;
            Thread thread = new Thread(() -> {
                // 对于每个线程,将数组按照元素值升序排序
                Arrays.sort(arr, index * 10, index * 10 + 10);
                sortedArrs[index] = Arrays.copyOfRange(arr, index * 10, index * 10 + 10);
                System.out.println(Thread.currentThread().getName() + "排序完成");
                latch.countDown(); // 线程完成后减少 CountDownLatch 的计数器
            });
            thread.start();
        }
        System.out.println("等待线程排序结束...");
        latch.await();
        System.out.println("所有线程排序操作均已完成");

        // 对排序后的三个数组进行合并操作
        int[] mergedArr = new int[30];
        System.arraycopy(sortedArrs[0], 0, mergedArr, 0, 10);
        System.arraycopy(sortedArrs[1], 0, mergedArr, 10, 10);
        System.arraycopy(sortedArrs[2], 0, mergedArr, 20, 10);
        Arrays.sort(mergedArr);

        System.out.println("合并后的数组:");
        System.out.println(Arrays.toString(mergedArr));
    }

    public static int[] generateArray(int len) {
        int[] arr = new int[len];
        Random random = new Random();
        for (int i = 0; i < len; i++) {
            arr[i] = random.nextInt(100);
        }
        System.out.println("生成的随机数组:");
        System.out.println(Arrays.toString(arr));
        return arr;
    }
}

运行上面的代码,你将得到以下输出:

生成的随机数组:
[70, 70, 82, 8, 35, 91, 80, 97, 46, 37, 44, 89, 50, 91, 48, 5, 70, 17, 24, 77, 43, 54, 37, 21, 67, 46, 45, 3, 73, 79]
等待线程排序结束...
Thread-0排序完成
Thread-2排序完成
Thread-1排序完成
所有线程排序操作均已完成
合并后的数组:
[3, 5, 8, 17, 21, 24, 35, 37, 37, 43, 44, 45, 46, 46, 50, 54, 67, 70, 70, 70, 73, 77, 79, 80, 82, 89, 91, 91, 97]

在上述代码中,我们通过 generateArray 方法生成了一个随机数组(用于排序操作),然后我们创建了三个子线程,每个线程排序数组的不同片段并将排序后的结果保存在 sortedArrs 数组中。每个子线程排序完成后,将会调用 countDown() 方法来使 CountDownLatch 中的计数器减 1。最后,我们在主线程中等待三个子线程排序完成后,对排序后的三个数组进行合并操作。

综上所述,我希望这个完整攻略能帮助你理解和使用 CountDownLatch 类,同时感受到多线程程序设计的魅力。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程CountDownLatch的实现 - Python技术站

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

相关文章

  • 解决JSONObject.toJSONString()输出null的问题

    当我们调用 JSONObject.toJSONString(obj) 方法时,如果 obj 对象中存在 null 值的属性,那么转换成 JSON 字符串时就会出现问题,最终输出 null 值或抛出异常。下面我们来详细讲解如何解决此问题,以下是完整攻略: 1. 基本原因 在 JSONObject.toJSONString() 方法中,会检查对象 obj 是否为…

    Java 2023年5月26日
    00
  • java使用common-fileupload实现文件上传

    下面是使用Commons FileUpload实现Java文件上传的完整攻略: 前提条件 在使用Commons FileUpload之前,需要确保你已经满足以下的条件: 已经安装了Java SDK(至少是1.6或以上版本) 已经使用Eclipse等集成开发环境,或者手动配置好了Java的CLASSPATH。 已经有一个能够接受文件上传请求的Java Web应…

    Java 2023年5月20日
    00
  • Spring Data Jpa+SpringMVC+Jquery.pagination.js实现分页示例

    下面我来详细讲解一下“Spring Data Jpa+SpringMVC+Jquery.pagination.js实现分页示例”的完整攻略。 1. 环境准备 首先,我们需要准备好以下环境: JDK 1.8 Spring Boot 2.3.4.RELEASE Spring Data JPA 2.3.4.RELEASE MySQL 8.0.21 Maven 3.…

    Java 2023年5月20日
    00
  • Spring在web.xml中的配置详细介绍

    根据题目的要求,我会给出一个“Spring在web.xml中的配置详细介绍”的完整攻略,包含以下内容: 概述 在web项目中,web.xml是一个非常重要的配置文件,它负责和web服务器打交道,告诉服务器如何处理请求并且将结果返回给客户端。在web.xml中加入Spring的配置信息可以让Spring框架和web服务器配合工作,实现更方便的编写web应用的过…

    Java 2023年6月15日
    00
  • 详解JAVA生成将图片存入数据库的sql语句实现方法

    下面我将详细讲解“详解JAVA生成将图片存入数据库的 SQL 语句实现方法”的完整攻略。 1. 前置条件 在进行本攻略中的操作前,需要具备以下前置条件: 已安装 Java 开发环境并配置好环境变量 已安装 MySQL 数据库并配置好数据库信息 已导入 JDBC 驱动包,可以连接 MySQL 数据库 2. JAVA 代码实现 以下是将图片存入数据库的 JAVA…

    Java 2023年5月19日
    00
  • Springboot 2.x集成kafka 2.2.0的示例代码

    下面我会详细讲解Springboot 2.x集成Kafka 2.2.0的示例代码的完整攻略。 前置条件:1. 已安装JDK和Maven;2. 已安装并起动好Zookeeper和Kafka。 步骤一:创建Springboot项目1. 打开IDEA,在左侧导航栏中选择New Project;2. 在弹出对话框中选择Spring Initializr,点击Next…

    Java 2023年5月20日
    00
  • jQuery表格插件datatables用法总结

    jQuery表格插件datatables用法总结 什么是datatables datatables是一款基于jQuery库的表格插件,它通过客户端无刷新式展示表格数据,并提供了搜索、分页、排序等功能,能够大大简化web应用程序的开发过程。 如何使用datatables 数据源准备 datatables可以直接使用HTML表格中的数据作为数据源,也可以通过AJ…

    Java 2023年6月16日
    00
  • java中throws实例用法详解

    Java中throws实例用法详解 什么是异常? 在编写 Java 代码的过程中,我们有时候会遇到一些错误,例如访问一个不存在的文件,访问 null 对象,或者调用方法时传入了非法参数等。这些错误被称为异常。 异常在运行时被抛出,程序会尝试去处理这个异常,如果未能处理,则会导致程序中断。Java 中的异常继承自 Java.lang.Throwable 类。 …

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