首页 > 编程语言 >Java中的CountDownLatch作用及使用场景

Java中的CountDownLatch作用及使用场景

时间:2025-01-07 11:58:01浏览次数:3  
标签:场景 Java int 计数器 线程 CountDownLatch new latch

CountDownLatch是Java并发编程中一个非常有用的同步辅助类,主要用于协调多个线程之间的执行顺序。它允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。本文将详细解释CountDownLatch的用途、工作机制以及在实际应用中的使用场景。

CountDownLatch的用途和解释

1. 同步辅助类

CountDownLatch是一个同步辅助类,用于在完成一组正在其他线程中执行的操作之前,允许一个或多个线程等待。它提供了一种机制,使得一个线程可以等待其他线程完成各自的任务后再继续执行。这种机制在多线程编程中非常有用,尤其是在需要确保某些初始化工作完成后再进行后续操作的场景中。

2. 计数器

CountDownLatch内部维护了一个计数器,该计数器的初始值是在创建CountDownLatch对象时指定的。每当一个线程完成了自己的任务后,可以调用countDown()方法来减少计数器的值。当计数器的值减到零时,所有调用await()方法并在此时被阻塞的线程将被唤醒并继续执行。

CountDownLatch的工作机制

  • 初始化:在创建CountDownLatch对象时,需要指定一个整数作为计数器的初始值。这个值表示需要等待的事件数量。

    CountDownLatch latch = new CountDownLatch(3);
    
  • 计数减少:每当一个线程完成了自己的任务后,可以调用countDown()方法来减少计数器的值。

    latch.countDown();
    

  • 等待:其他线程可以调用await()方法来等待计数器变为零。如果计数器不为零,调用await()方法的线程将会被阻塞,直到计数器变为零。

    latch.await();
    

使用场景

1. 并行任务的启动

在某些情况下,主线程需要等待多个子线程完成任务后再继续执行。例如,在启动一个服务器之前,可能需要确保所有的服务组件都已经初始化完成。这时可以使用CountDownLatch来实现这种同步机制。

public class Server {
    private static final int SERVICE_COUNT = 3;
    private final CountDownLatch latch = new CountDownLatch(SERVICE_COUNT);
    
    public void startServices() throws InterruptedException {
        for (int i = 0; i < SERVICE_COUNT; i++) {
            new Thread(() -> {
                // 模拟服务初始化
                try {
                    Thread.sleep((long) (Math.random() * 1000));
                    System.out.println("Service initialized");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    latch.countDown();
                }
            }).start();
        }
        latch.await(); // 等待所有服务初始化完成
        System.out.println("All services are up, starting server...");
    }
}
2. 多线程计算结果汇总

在进行多线程计算时,有时需要等待所有线程完成计算后再对结果进行汇总。例如,在并行处理一个大数据集时,可以将数据分成多个部分,每个线程处理一部分数据,最后主线程等待所有子线程完成计算后再进行结果汇总。

public class DataProcessor {
    private static final int THREAD_COUNT = 4;
    private final CountDownLatch latch = new CountDownLatch(THREAD_COUNT);
    private int[] results = new int[THREAD_COUNT];
    
    public void processData() throws InterruptedException {
        for (int i = 0; i < THREAD_COUNT; i++) {
            final int index = i;
            new Thread(() -> {
                // 模拟数据处理
                results[index] = index * index; // 假设这是计算结果
                latch.countDown();
            }).start();
        }
        latch.await(); // 等待所有数据处理完成
        int sum = 0;
        for (int result : results) {
            sum += result;
        }
        System.out.println("Total sum: " + sum);
    }
}
3. 测试并发代码

在编写并发代码的单元测试时,CountDownLatch可以帮助我们确保所有并发操作都已经完成,然后再进行断言和验证。这样可以保证测试的准确性和可靠性。

@Test
public void testConcurrentTasks() throws InterruptedException {
    final int threadCount = 5;
    final CountDownLatch latch = new CountDownLatch(threadCount);
    List<Thread> threads = new ArrayList<>();
    
    for (int i = 0; i < threadCount; i++) {
        Thread thread = new Thread(() -> {
            // 模拟任务执行
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                latch.countDown();
            }
        });
        threads.add(thread);
        thread.start();
    }
    latch.await(); // 等待所有任务完成
    assertEquals(0, latch.getCount()); // 确保所有任务都已完成
}

总结

CountDownLatch是Java并发编程中一个非常实用的同步辅助类,通过维护一个计数器,允许一个或多个线程等待一组在其他线程中执行的操作完成。它在多线程任务协调、并行计算结果汇总以及并发代码测试等场景中具有广泛的应用。理解和掌握CountDownLatch的使用,对于编写高效、可靠的并发程序至关重要。

标签:场景,Java,int,计数器,线程,CountDownLatch,new,latch
From: https://blog.csdn.net/luohuahui2012/article/details/144982123

相关文章

  • 16 个 JavaScript 简写神技,提效 60%!
    分享下16个最常用的JavaScript的简写技巧,掌握它们可以让我们编写出更简洁、更优雅的代码,并显著提升开发效率(增加摸鱼时间)1.三元运算符简化条件判断//传统写法letresult;if(someCondition){result='yes';}else{result='no';}//简写方式constresu......
  • 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-11- 标签页(tab)操作 - 下篇 (详细教
    1.简介本来按照计划这一系列的文章应该介绍Context和Page两个内容的,但是宏哥看了官方文档和查找资料发现其实和宏哥在Python+Playwright系列文章中的大同小异,差不了多少,再在这一个系列介绍就有点画蛇添足,索性就不介绍和讲解了,有兴趣的自己可以看宏哥之前写的,或者自己查找资料和官......
  • Java项目启动时的端口占用问题
    报错:name:com.x.server.console.command.StartCommand,message:Failedtobindtoaddress0.0.0.0/0.0.0.0:20040,checkconfiguration错误提示:无法绑定20040端口,即端口被其他进程占用。查看端口任务进程并清除占用进程:lsof-i:20040//查看进程kill-9$(lsof-t......
  • java集成stable diffusion
    集成StableDiffusion模型到Java应用程序中,可以实现先进的图像生成和处理功能。StableDiffusion模型通常用Python实现,但通过HTTPAPI或JNI(JavaNativeInterface),我们可以在Java中调用这些模型。以下是详细的集成方法。集成概述StableDiffusion是一个强大的图像生成模型,通常运......
  • JavaScript字符串的常用方法
    在JavaScript中,字符串处理是一个非常常见的任务。JavaScript提供了丰富的字符串操作方法,使开发者能够高效地处理和操作字符串。本文将详细介绍JavaScript字符串的常用方法,并提供示例代码以便更好地理解和应用这些方法。字符串长度获取字符串的长度是一个基本操作,可以使用 lengt......
  • JavaScript 实现支持过期时间的数据缓存功能
    JavaScript实现支持过期时间的数据缓存功能要在JavaScript中实现数据缓存功能并支持设置过期时间,可以使用localStorage、sessionStorage或内存对象(如Map或普通对象)来存储数据,并为每个缓存项设置一个过期时间。以下是一个简单的实现示例:JavaScript实现支持过期时间的数......
  • javascript如何判断浏览器是否支持严格模式?
    在JavaScript中,严格模式(StrictMode)是一种特殊的执行模式,它可以帮助开发者避免一些常见的错误,并提供更强的错误检查。要在JavaScript中启用严格模式,你需要在脚本或函数的顶部添加"usestrict";声明。然而,直接检测浏览器是否“支持”严格模式并不直接可行,因为严格模式不是浏览器的......
  • javascript设置"严格模式"有什么目的?
    设置JavaScript的“严格模式”有以下几个主要目的:消除JavaScript语法的不合理和不严谨之处:通过启用严格模式,可以帮助开发者避免一些在正常模式下可能被忽略的语法错误或不合理之处,从而使代码更加严谨和可靠。提高代码的安全性:严格模式采用了一些安全措施,例如禁止this关键字......
  • 使用javascript实现一个popup
    在前端开发中,实现一个基本的popup(弹出窗口)可以通过多种方式来完成,包括使用原生JavaScript、HTML和CSS。以下是一个简单的示例,展示了如何使用这些技术来创建一个基本的popup。HTML结构首先,在HTML文件中定义popup的结构。这通常包括一个背景遮罩(overlay)和一个包含内容的......
  • 高级java每日一道面试题-2025年01月05日-并发篇-什么是阻塞队列?阻塞队列的实现原理是
    如果有遗漏,评论区告诉我进行补充面试官:什么是阻塞队列?阻塞队列的实现原理是什么?如何使用阻塞队列来实现生产者-消费者模型?我回答:在Java高级面试中,阻塞队列是一个非常重要的概念,它涉及到多线程并发编程的核心知识。以下是对阻塞队列的详细解释,包括其定义、实现原......