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日

相关文章

  • Mysql InnoDB多版本并发控制MVCC详解

    Mysql InnoDB多版本并发控制MVCC详解 什么是MVCC? MVCC,全称为Multi-Version Concurrency Control,即多版本并发控制。是一种为了实现数据库并发控制的技术。 在数据库系统中,由于有多个用户会同时对数据库进行读写操作,如果多个用户同时对同一行记录进行操作,就会出现数据混乱的问题。传统的并发控制方法是通过加锁实…

    多线程 2023年5月16日
    00
  • PHP+shell实现多线程的方法

    针对 PHP+shell 实现多线程的方法,我可以提供以下完整攻略: 准备工作 在开始 PHP+shell 实现多线程操作之前,需要准备好以下工具: PHP解释器(Versions >= 5.3) shell命令行 Pcntl与pcntl_fork(PHP中的扩展) 实现方法 使用pcntl_fork()函数实现多进程操作: <?php $wor…

    多线程 2023年5月16日
    00
  • iOS中多网络请求的线程安全详解

    iOS中多网络请求的线程安全详解 背景 在iOS开发中,常常需要进行多个网络请求,这些网络请求有时需要同时进行,有时需要按照一定顺序进行,还有的情况则是必须等待前一个网络请求完成后才能进行下一个网络请求。面对这些情况,我们必须注意多线程编程中线程安全的问题。 线程安全问题 线程安全问题是多线程编程中必须注意的一个问题。多线程环境下,用于处理网络请求的对象和方…

    多线程 2023年5月17日
    00
  • python并发2之使用asyncio处理并发

    使用asyncio处理并发主要是通过协程和事件循环来实现,下面是使用asyncio处理并发的完整攻略。 1. 理解asyncio asyncio是python的一个异步IO库,可以提高IO操作的效率,同时支持并发编程模型。asyncio本质上是一个事件循环框架,它提供了Task、Future和协程等机制来实现异步处理和协作式多任务,可以避免因阻塞IO而导致的…

    多线程 2023年5月16日
    00
  • java多线程编程之Synchronized关键字详解

    Java多线程编程之Synchronized关键字详解 什么是Synchronized关键字 Synchronized是一种Java中的关键字,可以将一段代码标记为“临界区”,保证多个线程在执行该代码时不会发生冲突,保证数据的正确性。 Synchronized关键字的用法 Synchronized关键字可以用在方法或代码块上。 用在方法上 public sy…

    多线程 2023年5月16日
    00
  • Redis实现高并发计数器

    一、Redis实现高并发计数器 Redis提供了incr和decr两个命令,可以实现简单计数器功能。但是在高并发场景下,直接使用incr可能会存在并发问题,如多个客户端同时执行incr命令,会导致结果错误。为了解决这个问题,可以使用Redis的分布式锁机制,在incr命令前获取锁,执行完成后释放锁,从而避免并发问题。 步骤: 创建一个计数器key,初值为0,…

    多线程 2023年5月16日
    00
  • 了解java中的Clojure如何抽象并发性和共享状态

    了解Java中的Clojure如何抽象并发性和共享状态 Clojure是一种运行在Java虚拟机上的Lisp方言,它提供了对并发编程和共享状态的高度抽象能力。 Clojure的并发编程采用的是不可变的数据结构和函数式编程,这些特性可以让编写并发程序变得更为简单和安全。 下面我们将结合示例来详细讲解Clojure如何抽象并发性和共享状态。 Clojure中的不…

    多线程 2023年5月16日
    00
  • 深入分析JAVA 多线程–interrupt()和线程终止方式

    深入分析JAVA 多线程 – interrupt()和线程终止方式 前言 在多线程程序中,线程的终止是一个重要的主题。Java提供了多个API来让我们实现线程的终止。其中interrupt()方法是一个比较常用也比较容易被理解的API,同时也是本篇攻略的重点内容。 interrupt() 方法 在Java中,每个线程都有一个布尔类型(Boolean)的中断标…

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