countDownLatch-多个任务并行执行,等待相同的时间后,获取最终的结果

 线程池工具类:

package com.common.core.pool;

import io.netty.util.concurrent.DefaultThreadFactory;

import java.util.concurrent.*;

/**
 * @author
 */
public class CommonThreadPoolExecutor {
    
    /**
     * The core pool size.
     */
    private static final int CORE_POOL_SIZE = 8;
    /**
     * The max pool size.
     */
    private static final int MAXI_MUM_POOL_SIZE = 32;
    /**
     * The keepalive time.
     */
    private static final long KEEPALIVE_TIME = 120L;
    /**
     * block queue
     */
    private static final BlockingQueue<Runnable> BLOCKING_QUEUE_1 = new LinkedBlockingQueue<>(10000);
    private static final BlockingQueue<Runnable> BLOCKING_QUEUE_2 = new LinkedBlockingQueue<>(10000);
    
    /**
     * The thread name
     */
    private static final String THREAD_NAME_1 = "common-level-1";
    private static final String THREAD_NAME_2 = "common-level-2";
  
    
    /**
     * 线程池一
     */
    public static final ExecutorService EXECUTOR_LEVEL_1 = new java.util.concurrent.ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAXI_MUM_POOL_SIZE,
            KEEPALIVE_TIME,
            TimeUnit.SECONDS,
            BLOCKING_QUEUE_1,
            new DefaultThreadFactory(THREAD_NAME_1),
            new ThreadPoolExecutor.CallerRunsPolicy());
    
    /**
     * 线程池二
     */
    public static final ExecutorService EXECUTOR_LEVEL_2 = new java.util.concurrent.ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAXI_MUM_POOL_SIZE,
            KEEPALIVE_TIME,
            TimeUnit.SECONDS,
            BLOCKING_QUEUE_2,
            new DefaultThreadFactory(THREAD_NAME_2),
            new ThreadPoolExecutor.CallerRunsPolicy());
    
    
}

countDownLatch的使用:

List<Student> students = new ArrayList<>();
List<Teacher> teachers = new ArrayList<>();
CountDownLatch countDownLatch = new CountDownLatch(4);

CommonThreadPoolExecutor.EXECUTOR_LEVEL_2.execute(() -> {
            List<Student> studentList = getStudentList();
            students.addAll(studentList);
            countDownLatch.countDown();
});
       
CommonThreadPoolExecutor.EXECUTOR_LEVEL_2.execute(() -> {
            List<Teacher> teacherList = getTeacherList();
            teachers.addAll(teacherList);
            countDownLatch.countDown();
});
try {
     countDownLatch.await(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
     e.printStackTrace();
}

<think>好的,我现在需要解决用户的问题:如何在多线程环境中统计1000个任务执行完毕所花费的总时间。用户可能是在开发一个需要高效处理多任务的应用程序,比如数据处理、网络请求或者并行计算。他们可能遇到了性能瓶颈,或者想优化任务执行时间,所以想知道如何准确测量多线程任务的总耗时。 首先,我得回忆多线程的基本概念。多线程允许程序同时执行多个任务,提高效率,特别是在多核CPU上。但统计总时间需要考虑线程同步的问题,因为主线程需要等待所有子线程完成才能计算总耗时。如果主线程不等待,可能会提前结束,导致统计的时间不准确。 接下来,用户提到1000个任务,可能需要使用线程池来管理线程,避免频繁创建和销毁线程的开销。Java中的ExecutorService或者Python的concurrent.futures模块可能适用。不过用户的问题没有指定编程语言,可能需要给出通用的方法或者示例。 然后,关键点是如何同步所有任务的完成。常见的方法包括使用计数器、闭锁(如CountDownLatch)、栅栏(CyclicBarrier)或者Future对象。例如,在Java中,CountDownLatch初始化一个计数器,每个任务完成时计数器减一,主线程等待计数器归零。在Python中,可以使用ThreadPoolExecutor并收集所有Future对象,然后等待它们全部完成。 另外,需要考虑时间测量的准确性。开始时间应该在所有任务提交后、开始执行前记录,而结束时间应该在所有任务完成后立即记录。在线程池中,任务提交和执行可能有延迟,所以需要确保任务真正开始执行的时间点被正确捕获。 可能遇到的问题包括线程间的竞争条件、任务执行时间差异较大导致某些线程长时间运行,以及如何正确处理异常不影响总时间的统计。此外,如果使用线程池任务可能被排队而不是立即执行,这时候总时间可能包括等待时间,需要根据具体情况分析。 用户提供的引用中有提到CountDownLatch线程池的使用,比如引用[4]和引用[5],可能相关的实现方法。例如,在Java中,使用ExecutorService提交任务,结合CountDownLatch等待所有任务完成,然后计算时间差。在Python中,可以使用concurrent.futures的wait方法或者as_completed,但需要确保所有任务完成后再计算时间。 还需要考虑的是,多线程环境下,时间统计是否受到线程调度的影响。比如,主线程和子线程之间的启动和结束时间是否精确同步。可能需要使用系统的高精度时间函数,如System.nanoTime()在Java中,或者time.perf_counter()在Python中。 总结步骤应该是: 1. 记录开始时间。 2. 创建并启动所有线程或提交任务线程池。 3. 主线程等待所有任务完成(使用同步工具)。 4. 记录结束时间。 5. 计算总耗时(结束时间 - 开始时间)。 需要根据不同的编程语言给出具体实现示例,比如Java和Python,或者通用的伪代码。同时,要提醒用户注意线程安全和同步机制的选择,避免数据竞争和死锁。 可能用户还想知道如何优化多线程任务的执行时间,或者如何处理任务中的异常,但这些可能超出了当前问题的范围。不过,在回答中可以简要提及这些优化点作为扩展思考。 最后,确保回答结构清晰,分步骤说明,并给出代码示例,同时引用相关的参考文献,如用户提供的引用[4]关于CountDownLatch的使用和引用[5]关于线程池的参数设置。</think>在多线程环境中统计1000个任务执行总耗时,需通过线程同步机制确保主线程等待所有子任务完成后再计算时间差。以下是分步实现方法及示例代码: --- ### **方法一:使用CountDownLatch(适用于Java)** 1. **初始化计数器**:创建$count=1000$的`CountDownLatch`[^4] 2. **记录开始时间**:提交所有任务获取系统时间$t_1$ 3. **提交任务线程池**:每个任务完成后调用`countDown()` 4. **主线程阻塞等待**:调用`latch.await()`直到计数器归零 5. **计算总耗时**:获取当前时间$t_2$,总耗时$\Delta t = t_2 - t_1$ ```java ExecutorService executor = Executors.newFixedThreadPool(10); CountDownLatch latch = new CountDownLatch(1000); long startTime = System.nanoTime(); for (int i = 0; i < 1000; i++) { executor.submit(() -> { try { // 执行任务逻辑 } finally { latch.countDown(); } }); } latch.await(); long totalTime = System.nanoTime() - startTime; executor.shutdown(); ``` --- ### **方法二:使用线程池的Future(适用于Python)** 1. **创建线程池**:通过`ThreadPoolExecutor`管理线程[^5] 2. **提交任务并记录Future对象**:使用`submit()`返回Future列表 3. **统一等待所有任务完成**:调用`wait()`或`as_completed()` 4. **时间差计算**:使用高精度计时器如`time.perf_counter()` ```python from concurrent.futures import ThreadPoolExecutor import time start_time = time.perf_counter() with ThreadPoolExecutor(max_workers=10) as executor: futures = [executor.submit(task_function) for _ in range(1000)] for future in futures: future.result() # 阻塞直到所有任务完成 total_time = time.perf_counter() - start_time ``` --- ### **关键注意事项** 1. **时间精度**:使用高精度计时函数(如Java的`System.nanoTime()`、Python的`time.perf_counter()`) 2. **线程池配置**:合理设置线程数(通常等于CPU核心数)[^2] 3. **异常处理**:在任务逻辑中添加`try-finally`块避免计数器未递减 4. **资源释放**:任务完成后及时关闭线程池[^5] --- ### **扩展优化方向** - **动态任务分配**:使用`CyclicBarrier`或`CompletableFuture`处理复杂依赖 - **异步回调**:通过回调函数记录单个任务耗时(需考虑线程安全) - **性能分析**:结合火焰图或性能分析工具定位瓶颈[^1] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值