Java实现限定时间CountDownLatch并行场景

yizhihongxing

让我们详细讲解“Java实现限定时间CountDownLatch并行场景”的完整攻略。

CountDownLatch概述

CountDownLatch是Java中一个非常实用的工具,它可以用于协调多个线程之间的同步操作。它可以让等待某个特定条件发生的线程一直等待下去,直到该条件被满足后,所有等待的线程才会同时被唤醒并继续执行。

CountDownLatch的核心思想就是一个计数器,该计数器被初始化为一个正整数,并且在某些操作发生之后被递减。一组等待中的线程可以被阻塞,直到计数器为零。如果你只是需要一个简单的同步工具,并不像Semaphore这样复杂和强大,那么CountDownLatch是个不错的选择。

CountDownLatch的使用

CountDownLatch的使用比较简单,主要包括以下步骤:

  1. 创建一个CountDownLatch对象,并指定计数器的初始值(即需要等待的操作数)。
  2. 在工作线程中执行需要等待的操作。
  3. 在等待线程中使用await()方法等待操作完成。
  4. 在工作线程中完成每个操作时,使用countDown()方法递减计数器的值。

Java实现限定时间CountDownLatch并行场景攻略及示例代码

Java实现限定时间CountDownLatch并行场景攻略的步骤如下:

  1. 创建一个 CountDownLatch 对象,计数器的初始值设为要等待的操作数 N,即需要等待 N 个线程的操作完成。
  2. 在每个工作线程中执行相应的任务,然后使用 countDown() 方法递减计数器的值。如果递减后的值为0,则所有操作已完成。
  3. 在等待线程中,调用 await(long timeout, TimeUnit unit) 方法等待操作完成或超时。超时时间可以由参数指定。

下面是示例代码,其中有两个工作线程并行执行,主线程等待它们完成或超时:

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class CountDownLatchDemo {
    private static final int WORKER_NUM = 2;
    private static final int WAIT_TIME = 5000;

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(WORKER_NUM);

        // 创建两个工作线程
        new Thread(new Worker(latch, "Worker1")).start();
        new Thread(new Worker(latch, "Worker2")).start();

        // 在主线程中等待操作完成或超时
        if (latch.await(WAIT_TIME, TimeUnit.MILLISECONDS)) {
            System.out.println("All workers finished the job!");
        } else {
            System.out.println("Timeout! Some workers are not finished yet.");
        }
    }

    // 工作线程
    static class Worker implements Runnable {
        private final CountDownLatch latch;
        private final String name;

        public Worker(CountDownLatch latch, String name) {
            this.latch = latch;
            this.name = name;
        }

        @Override
        public void run() {
            try {
                // 执行任务
                System.out.println(name + " is starting to work...");
                TimeUnit.SECONDS.sleep(3);
                System.out.println(name + " finished the job!");

                // 递减计数器
                latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在上述示例代码中,创建了一个 CountDownLatch 对象 latch,并指定初始值为 2(即需要等待两个工作线程完成操作)。然后创建两个工作线程 Worker1 和 Worker2,在每个工作线程中执行相应任务,最终使用 countDown() 方法递减计数器的值。在主线程中使用 await(long timeout, TimeUnit unit) 方法等待两个工作线程完成操作或超时。如果所有工作线程在指定的时间内完成操作,主线程输出 "All workers finished the job!"。如果有任何一个工作线程还没有完成操作,则主线程输出 "Timeout! Some workers are not finished yet."。

另外,这里再给一个更实际的例子,假如我们需要在10秒内获取多个网站的内容,而每个网站的内容获取可能会需要不同时间,此时我们可以使用CountDownLatch来实现并行获取,然后将结果进行合并。具体操作流程如下:

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

public class CountDownLatchDemo {
    private static final int NUM_SITES = 5;
    private static final int WAIT_TIME = 10;
    private static final Random random = new Random();

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(NUM_SITES);
        List<String> contents = new ArrayList<>();

        // 并行获取各个网站的内容
        for (int i = 0; i < NUM_SITES; i++) {
            new Thread(new SiteContentFetcher(latch, contents)).start();
        }

        // 等待所有网站的内容获取完成或超时
        if (latch.await(WAIT_TIME, TimeUnit.SECONDS)) {
            System.out.println("All site contents fetched: " + contents);
        } else {
            System.out.println("Timeout!");
        }
    }

    // 获取单个网站的内容
    static class SiteContentFetcher implements Runnable {
        private final CountDownLatch latch;
        private final List<String> contents;

        public SiteContentFetcher(CountDownLatch latch, List<String> contents) {
            this.latch = latch;
            this.contents = contents;
        }

        @Override
        public void run() {
            try {
                // 模拟获取网站内容的时间
                long time = random.nextInt(10);
                System.out.println(Thread.currentThread().getName() + " fetching site content, time: " + time);
                TimeUnit.SECONDS.sleep(time);

                // 保存网站内容
                contents.add(Thread.currentThread().getName() + ": content");
                System.out.println(Thread.currentThread().getName() + " finished fetching site content");

                // 递减计数器
                latch.countDown();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

在上述示例代码中,创建了一个 CountDownLatch 对象 latch,并指定初始值为 NUM_SITES(即需要等待 NUM_SITES 个网站的内容获取完成)。然后创建 NUM_SITES 个获取网站内容的工作线程,在每个工作线程中模拟获取网站内容的时间,实际获取网站内容并将其保存到列表中,最后使用 countDown() 方法递减计数器的值。在主线程中使用 await(long timeout, TimeUnit unit) 方法等待所有工作线程完成操作或超时。如果所有工作线程在指定的时间内完成操作,主线程输出获取到的所有网站内容。如果某个工作线程还没有完成操作,则主线程输出 "Timeout!"。

以上就是关于Java实现限定时间 CountDownLatch 并行场景的完整攻略和两个示例代码。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java实现限定时间CountDownLatch并行场景 - Python技术站

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

相关文章

  • 使用SpringBoot+AOP实现可插拔式日志的示例代码

    下面是使用SpringBoot+AOP实现可插拔式日志的完整攻略。 什么是SpringBoot+AOP Spring AOP(Aspect Oriented Programming)是Spring框架中的一个重要模块,用于将额外的行为(横切逻辑)注入到系统中的特定点。SpringBoot是Spring框架的一个特殊版本,通过预先配置好常用的Bean并提供自动…

    Java 2023年5月20日
    00
  • js构造函数constructor和原型prototype原理与用法实例分析

    那么让我来详细讲解一下“js构造函数constructor和原型prototype原理与用法实例分析”的完整攻略。 什么是构造函数constructor? 在 JavaScript 中,构造函数是一种用于创建对象并初始化其属性的特殊函数。每个对象都是由一个构造函数生成的,JavaScript 内置了很多构造函数,比如 Array、String 等。 构造函数…

    Java 2023年5月23日
    00
  • Java线程池高频面试题总结

    Java线程池高频面试题总结 线程池是什么 线程池是一种用于管理多个线程的机制,它能够根据应用程序需要动态地增减线程。线程池在执行完任务后并不会立即销毁线程,而是将线程放入池中等待下一次使用。线程池通常会预先准备好一定数量的线程,这些线程被称为核心线程,在需要时更多的线程将被创建。 为什么使用线程池 线程池有以下优点: 减少线程创建的开销: 创建线程需要花费…

    Java 2023年5月19日
    00
  • Java ArrayList与LinkedList使用方法详解

    Java ArrayList与LinkedList使用方法详解 在Java中,常用的数据结构有ArrayList和LinkedList,这两种结构都可以用来存储一系列的数据。本文将详细讲解这两种结构的使用方法,以及它们之间的区别和适用场景。 ArrayList 基本使用方法 ArrayList是基于动态数组实现的,它的大小可以根据实际存储的元素动态变化。下面…

    Java 2023年5月29日
    00
  • Java超详细讲解三大特性之一的多态

    Java多态性 Java三大特性之一的多态,是Java面向对象编程的核心概念之一。本文将详细讲解Java多态性的基本概念、实现方法以及使用场景。 多态性的基本概念 多态性(Polymorphism)是指同一个方法名可以在不同的对象上有不同的实现方式,也可以理解为一种类型的普遍性和多样性。多态性分为两种类型: 静态多态性(编译时多态性):在编译期就可以确定具体…

    Java 2023年5月26日
    00
  • Java transient 关键字是干啥的

    当Java中的对象被序列化时,它们的所有属性(包括私有属性)都将被保存。在某些情况下,某些属性可能不想被序列化。在这种情况下,使用Java中的transient关键字进行标记,表示该属性不应该被序列化,并且不存储在返回的字节数组中。 在Java中,transient是一个关键字,用于标记类成员变量,通常用于序列化和反序列化。 Markdown 格式 在Mar…

    Java 2023年5月20日
    00
  • Python学习笔记整理3之输入输出、python eval函数

    Python 学习笔记整理3:输入输出、python eval函数 在本次学习笔记中,我们将会学习和回顾以下内容: Python中的输入输出 Python 中的文件读写 Python中的 eval函数 一、Python中的输入输出 在 Python 中,我们可以使用 print() 函数和 input() 函数来进行标准输入输出。 1. print() 函数…

    Java 2023年5月23日
    00
  • 详解如何在spring boot中使用spring security防止CSRF攻击

    当开发一个基于web的应用程序时,防止CSRF攻击是非常重要的步骤。Spring Security提供了很多的功能和配置选项,旨在帮助我们保护Web应用程序。以下是在Spring Boot中使用Spring Security防止CSRF攻击的完整攻略。 1.添加Spring Security依赖 我们需要在项目的pom.xml文件中添加spring-boot…

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