java线程并发控制同步工具CountDownLatch

当多个线程并发执行时,可能会出现资源争抢、数据不一致等问题。因此,Java 提供了一些同步工具来帮助我们实现线程并发控制。其中,CountDownLatch 是一个非常实用的同步工具,它可以使线程等待其他线程执行完成再继续执行。

CountDownLatch 的概述

CountDownLatch 是 Java.util.concurrent 包下的一个同步工具,它主要用于线程之间的协调。它可以让某个线程等待其他线程完成后再继续执行。

CountDownLatch 的工作原理很简单:它有一个计数器,当计数器的值变为 0 时,所有等待者(调用 CountDownLatch.await() 的线程)开始执行。而 CountDownLatch.countDown() 方法可以让计数器的值减 1。

CountDownLatch 的使用示例

示例1 让多个线程按顺序执行

假设有 3 个线程 a、b、c,希望它们按顺序执行,即先执行 a,然后 b,最后 c。可以使用 CountDownLatch 来实现。

public class Demo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(2); // 初始化计数器为2
        Thread a = new Thread(() -> {
            System.out.println("a");
            latch.countDown(); // 计数器减1
        });
        Thread b = new Thread(() -> {
            try {
                latch.await(); // 等待计数器变为0
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("b");
            latch.countDown();
        });
        Thread c = new Thread(() -> {
            try {
                latch.await(); // 等待计数器变为0
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("c");
        });

        a.start();
        b.start();
        c.start();
        a.join();
        b.join();
        c.join();
    }
}

在上面的示例中,我们初始化了一个计数器为 2 的 CountDownLatch 对象 latch。当线程 a 执行完后,调用 latch.countDown() 方法,计数器的值变为 1;然后线程 b 调用 await() 方法等待计数器变为 0,即等待线程 a 执行完;当线程 a 执行完后,调用一次 latch.countDown() 方法,其中的 count 就为 1,然后线程 b 再次调用 await() 方法等待计数器变为 0;同理,当线程 b 执行完后,调用一次 latch.countDown() 方法,计数器的值变为 0,线程 c 被唤醒,执行完毕。

示例2 计算多线程执行时间

下面的示例演示了如何计算多线程的执行时间。首先,定义一个 CountDownLatch 对象,让主线程在等待所有子线程执行完成后再统计时间。然后,定义若干个线程,在每个线程中执行一定时间的任务。在每个线程的任务执行完成后,调用 CountDownLatch.countDown() 方法,使计数器值减 1。当计数器值为 0 时,主线程被唤醒,统计时间。

public class Test {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch doneLatch = new CountDownLatch(5); // 5个线程完成
        long start = System.currentTimeMillis();

        for (int i = 0; i < 5; i++) {
            new Thread(() -> {
                try {
                    Thread.sleep(new Random().nextInt(3000)); // 模拟不同的线程执行时间
                    System.out.println(Thread.currentThread().getName() + " 执行完毕");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    doneLatch.countDown(); // 任务完成,计数器减 1
                }
            }, "Thread-" + i).start();
        }

        doneLatch.await(); // 等待所有线程执行完成
        long end = System.currentTimeMillis();
        System.out.println("所有线程执行时间:" + (end - start) + " 毫秒");
    }
}

在上面的示例中,我们创建了 5 个线程,每个线程执行时间随机(3000 毫秒以内),完成后调用 CountDownLatch.countDown() 方法。主线程等待所有线程执行完后统计时间,并输出结果。

结论

CountDownLatch 是一个非常实用的同步工具,可以帮助我们实现线程之间的协调。在多线程编程中,我们可以使用它来使某个线程等待其他线程执行完毕、按顺序执行多个线程、统计多个线程的执行时间等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java线程并发控制同步工具CountDownLatch - Python技术站

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

相关文章

  • Java Socket+多线程实现多人聊天室功能

    下面我们逐步讲解如何利用Java Socket和多线程实现多人聊天室功能: 1.建立Socket连接 首先,需要建立服务端和客户端的Socket连接。服务端需要绑定一个端口,等待客户端连接,而客户端则需要提供服务端的IP地址和端口号来连接服务端。 服务端代码示例: public static void main(String[] args){ try { S…

    多线程 2023年5月16日
    00
  • Java Lambda表达式原理及多线程实现

    下面是对于“Java Lambda表达式原理及多线程实现”的完整攻略。 什么是Lambda表达式 Lambda表达式是Java 8引入的一个新特性,它主要是为了简化一个接口(或者抽象类)的实现,从而使得代码更加简洁易读。Lambda表达式的本质是一个匿名函数,它没有名称,但是具备参数列表和方法体。 Lambda表达式有如下的语法格式: (parameters…

    多线程 2023年5月17日
    00
  • java项目中的多线程实践记录

    Java项目中的多线程实践记录 Java作为一种后端语言,在许多场景中需要使用多线程来提高效率和性能。在本文中,我将分享如何在Java项目中实践多线程,并包含两个示例说明。 多线程的基础概念 在Java中,线程是一种轻量级的对象,可以同时执行多个线程。在一个进程中,通常有多个线程运行,这些线程共享进程的内存和资源。线程可以被看作是轻量级的进程,需要特别注意并…

    多线程 2023年5月17日
    00
  • Spring-Boot中如何使用多线程处理任务方法

    关于Spring Boot中如何使用多线程处理任务,有以下几种方法: 方式一:使用Java中的Thread或Executor 可以使用Java中的Thread或Executor进行多线程处理任务,具体操作步骤如下: 在Spring Boot应用主类中创建ExecutorService: @Bean public ExecutorService executo…

    多线程 2023年5月16日
    00
  • 关于dubbo 自定义线程池的问题

    关于 Dubbo 自定义线程池的问题,我们可以按照以下步骤进行攻略: 1. 了解 Dubbo 线程模型 在 Dubbo 中,每个服务提供者都会有线程池,用于处理消费者的请求。Dubbo 的线程模型分为以下两种: 共享线程池模型(默认):每个服务提供者使用一个全局的线程池处理所有请求; 独享线程池模型:每个服务提供者为每个消费者维护一个线程池,处理该消费者的所…

    多线程 2023年5月17日
    00
  • 关于Java 并发的 CAS

    CAS(Compare and Swap)是一种并发机制,用于实现原子性操作。在并发编程中,当多个线程同时对共享变量进行操作时,会产生竞争条件(Race Condition),导致数据的不一致性、丢失、覆盖等问题。CAS机制通过比较期望值与实际值的方式,来确保正确性与一致性。 CAS的原理 CAS操作包括三个操作数:内存位置(V)、预期原值(A)和新值(B)…

    多线程 2023年5月17日
    00
  • 如何用PHP实现多线程编程

    创建多线程程序可以增加应用程序的效率,对于 PHP 程序员来说,也要掌握多线程编程技术。 实现 PHP 多线程编程的方式有很多,比如使用 pthreads 扩展、使用 pcntl 扩展、使用多进程(fork)等。下面我们举两个例子分别介绍使用 pthreads 扩展和多进程实现多线程编程的方法。 使用 pthreads 扩展 pthreads 扩展是一个多线…

    多线程 2023年5月17日
    00
  • Mysql事务并发问题解决方案

    那我来详细讲解一下 MySQL 事务并发问题的解决方案。 什么是 MySQL 事务并发问题 并发问题指多个用户同时访问同一份数据时,由于读写操作的顺序不同,产生了冲突,导致数据出现异常。MySQL 数据库在支持事务的同时,也存在并发问题。 比如,用户 A 和用户 B 同时对一个数据进行操作,A 想要写入数据,B 想要读取数据。若此时 B 先读取了数据,但 A…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部