使用ExecutorService和CountDownLatch的方法示例

在Java中,当使用线程池(如ExecutorService)来执行异步任务时,通常需要知道所有任务是否都已经完成。ExecutorService接口提供了几种方式来处理这种情况,但最常用的是shutdown()和awaitTermination()方法的组合,或者使用Future和CompletionService。这里我将提供一个使用ExecutorService和CountDownLatch的示例,因为CountDownLatch提供了一种直观的方式来等待一组线程完成。

首先,我们定义几个任务,然后使用ExecutorService来异步执行它们,并使用CountDownLatch来等待所有任务完成。

import java.util.concurrent.*;

public class ThreadPoolExample {

    public static void main(String[] args) throws InterruptedException {
        // 创建一个包含固定数量线程的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(4);

        // 定义任务数量
        int taskCount = 10;

        // 使用CountDownLatch来等待所有任务完成
        final CountDownLatch latch = new CountDownLatch(taskCount);

        // 提交任务到线程池
        for (int i = 0; i < taskCount; i++) {
            int taskId = i;
            executorService.submit(() -> {
                // 模拟任务执行
                try {
                    Thread.sleep(1000); // 假设每个任务需要1秒
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("任务 " + taskId + " 完成");
                // 每完成一个任务,计数减一
                latch.countDown();
            });
        }

        // 等待所有任务完成
        System.out.println("等待所有任务完成...");
        latch.await(); // 阻塞当前线程,直到latch的计数达到零
        System.out.println("所有任务完成!");

        // 关闭线程池
        executorService.shutdown();

        // 可选:等待线程池中的线程都执行完毕
        try {
            if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {
                // 线程池没有在规定时间内关闭,则强制关闭
                executorService.shutdownNow();
            }
        } catch (InterruptedException e) {
            // 当前线程在等待过程中被中断
            executorService.shutdownNow();
            Thread.currentThread().interrupt();
        }
    }
}

在这个例子中,我们首先创建了一个固定大小的线程池(这里使用4个线程)。然后,我们定义了一个CountDownLatch,其计数被初始化为任务的数量(这里为10)。对于每个任务,我们都向线程池提交了一个Runnable,其中包含了任务的执行逻辑和latch.countDown()调用,以确保每次任务完成时都会减少CountDownLatch的计数。

主线程通过调用latch.await()来等待,直到所有任务都调用了countDown()(即计数达到零),然后才能继续执行。这确保了主线程会等待所有任务完成后再继续。

最后,我们关闭了线程池,并通过调用awaitTermination()来可选地等待线程池中的所有线程都执行完毕。如果线程池没有在指定时间内关闭,则调用shutdownNow()来尝试立即停止所有正在执行的任务。

这个示例提供了处理异步任务并等待它们完成的一种有效方式,适用于需要等待所有任务完成再继续的场景。

标签:游戏攻略