java并发编程专题(八)—-(JUC)实例讲解CountDownLatch

让我来为您详细讲解“Java并发编程专题(八)——(JUC)实例讲解CountDownLatch”的完整攻略。

什么是 CountDownLatch

CountDownLatch,中文翻译为倒数计数器,是 Java 标准库 java.util.concurrent 包下的一个工具类,用于控制一个或多个线程等待多个线程操作完成之后再执行。

CountDownLatch 类位于 java.util.concurrent 包下,是一个线程同步的工具类,它可以让某一个线程等待直到计数器减为 0 后再继续执行。CountDownLatch 类只提供了一个构造器:

public CountDownLatch(int count)

参数 count 表示需要等待的线程数,这个参数只能被设置一次,而且 CountDownLatch 类没有提供任何加减操作,计数器只能在构造方法中初始化。当 count 值为 0 时,表示所有需要等待的线程都已经执行完毕,等待的线程会继续执行。

CountDownLatch 使用示例

下面我们通过两个实例来说明 CountDownLatch 的具体使用。

示例一:多线程处理任务计算总耗时

假设我们有一个任务,需要分布式处理,我们需要统计总的时间,通过使用 CountDownLatch 可以方便地实现这个需求。

import java.util.concurrent.CountDownLatch;

public class TaskProcessor {
    public static void main(String[] args) throws InterruptedException {
        int nThreads = 10;
        CountDownLatch startSignal = new CountDownLatch(1);
        CountDownLatch doneSignal = new CountDownLatch(nThreads);

        for (int i = 0; i < nThreads; i++) {
            new Thread(new Worker(startSignal, doneSignal)).start();
        }

        long start = System.currentTimeMillis();
        startSignal.countDown();
        doneSignal.await();
        long end = System.currentTimeMillis();

        System.out.println("Total time: " + (end - start) + "ms");
    }

    static class Worker implements Runnable {
        private final CountDownLatch startSignal;
        private final CountDownLatch doneSignal;

        Worker(CountDownLatch startSignal, CountDownLatch doneSignal) {
            this.startSignal = startSignal;
            this.doneSignal = doneSignal;
        }

        public void run() {
            try {
                startSignal.await();
                // 模拟耗时操作
                Thread.sleep((long)(Math.random() * 1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("Processed: " + Thread.currentThread().getName());

            doneSignal.countDown();
        }
    }
}

上面这个例子使用了两个 CountDownLatch,一个是 startSignal,一个是 doneSignal。startSignal 用于让所有线程在 startSignal 调用 countDown() 后同时执行,doneSignal 用于标记所有线程执行完毕。在主线程中,我们会调用 startSignal 的 countDown() 方法,让所有线程同时执行,并在 doneSignal.await() 处等待所有线程执行完毕,最后统计总的时间。

示例二:多个线程等待单个线程执行完成后再继续执行

假设我们有一个 Main 线程和多个 Sub 线程。我们希望 Main 线程等待所有的 Sub 线程执行完毕再继续执行。

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {
    static CountDownLatch countDownLatch = new CountDownLatch(1);

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        countDownLatch.await();
                        System.out.println(Thread.currentThread().getName() + " 执行完毕");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }

        Thread.sleep(3000);
        System.out.println("Main 线程执行完毕");
        countDownLatch.countDown();
    }
}

运行结果如下:

Thread-0 执行完毕
Thread-2 执行完毕
Thread-3 执行完毕
Thread-4 执行完毕
Thread-1 执行完毕
Main 线程执行完毕

在上面这个例子中,我们创建了一个 CountDownLatch 对象,然后创建了多个线程,调用了 countDownLatch.await() 方法。在 Main 线程执行完成后,调用了 countDownLatch.countDown() 方法,此时所有的线程同时开始执行。

总的来说,CountDownLatch 是一个非常方便的多线程工具类,可以实现多个线程的同步。我们可以使用它来实现复杂的分布式计算等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java并发编程专题(八)—-(JUC)实例讲解CountDownLatch - Python技术站

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

相关文章

  • Redis高并发情况下并发扣减库存项目实战

    Redis高并发情况下并发扣减库存项目实战 项目背景 很多电商平台在购物高峰期会面临商品库存不足的问题,而库存紧张问题不但要求电商平台提高库存的数量,也要求电商平台优化库存的流程,实现高效扣减库存。 本项目利用Redis实现库存扣减,具体做法是:每次库存变动可以作为一个事务放到Redis的事务队列中,通过WATCH命令加锁机制,避免并发扣减库存冲突。 项目实…

    多线程 2023年5月16日
    00
  • collection集合体系与并发修改异常的解决方法

    下面我来详细讲解“collection集合体系与并发修改异常的解决方法”。 一、collection集合体系介绍 Java的集合体系分为List、Set、Map三种,它们分别对应了序列、集合和映射这三个数学概念。 List是有序的,更像是一个数组,但它不存在固定长度的限制,可以动态增加删除,比数组更灵活方便。List常用的实现类包括ArrayList、Lin…

    多线程 2023年5月16日
    00
  • MySQL事务的ACID特性以及并发问题方案

    MySQL事务的ACID特性和并发问题方案是数据库设计中非常重要的话题。下面我将详细解释ACID特性以及如何解决并发问题,同时提供两个示例说明。 ACID特性 ACID是指数据库事务所需满足的四个特性: 原子性:事务是一个原子操作,要么全部执行,要么全部不执行。 一致性:事务执行前后,数据库中的数据必须保持一致状态。 隔离性:事务在执行时,不受其他事务的干扰…

    多线程 2023年5月16日
    00
  • Java进阶之高并发核心Selector详解

    Java进阶之高并发核心Selector详解 什么是Selector Selector 是 Java NIO 中的一部分,它是一个可以通过单个线程处理多个 Channel 的组件。 在传统的 IO 模型中,每个连接都需要独立的线程进行处理,而使用 Selector 后,可以使用一个线程来处理多个连接,从而提高了程序的并发处理能力。 Selector 的使用 …

    多线程 2023年5月17日
    00
  • Java并发编程多线程间的同步控制和通信详解

    Java并发编程多线程间的同步控制和通信详解 背景介绍 在多线程并发编程中,控制多个线程的同步和通信是非常重要的话题。如果多个线程之间没有良好的同步控制和通信机制,就会导致数据竞争、死锁、饥饿等问题,从而降低程序的性能和可靠性。因此,在Java并发编程中,多线程间的同步控制和通信是一项非常重要的技能。 同步控制 什么是同步控制? 同步控制是一种机制,用于确保…

    多线程 2023年5月16日
    00
  • java多线程之CyclicBarrier的使用方法

    Java多线程之CyclicBarrier的使用方法 简介 CyclicBarrier是Java多线程中的一个工具类,它可以用来构建可重用的同步对象,可以让一组线程在到达某个屏障时阻塞,直到所有的线程都到达屏障时,在继续执行。与CountDownLatch类似,都是多线程同步工具,但CyclicBarrier可以通过它的reset()方法,重用一次。 Cyc…

    多线程 2023年5月16日
    00
  • 聊聊java多线程创建方式及线程安全问题

    那么让我们来聊聊Java多线程创建方式及线程安全问题的完整攻略。 1. Java多线程的创建方式 Java中创建多线程有两种方式,一种是继承Thread类,另一种是实现Runnable接口。 1.1 继承Thread类 示例代码如下: class MyThread extends Thread { public void run() { System.out…

    多线程 2023年5月16日
    00
  • Java并发编程中使用Executors类创建和管理线程的用法

    一、介绍 在Java并发编程中,线程池是一种重要的技术。通过线程池执行任务可以大大减少资源的开销,提高程序的性能,避免线程过多导致系统资源耗尽的情况。而Executors类就是Java提供的一个专门用于创建和管理线程池的工具类。 二、使用步骤 创建线程池 创建线程池的方式有多种,其中Executors类提供了丰富的静态方法来创建不同类型的线程池。比较常用的是…

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