首页 > 编程语言 >java异步判断线程池所有任务是否执行完

java异步判断线程池所有任务是否执行完

时间:2025-01-06 12:34:27浏览次数:7  
标签:异步 java CompletionService -- 任务 线程

在Java中,使用线程池(ExecutorService)可以高效地管理和执行异步任务。对于某些应用场景,可能需要异步地判断线程池中所有任务是否执行完毕。以下是一个高度专业的指南,讲解如何在Java中实现这一功能。

步骤概述

  1. 创建并配置线程池。
  2. 提交多个异步任务到线程池。
  3. 使用 CompletionService来监控任务的完成情况。
  4. 实现异步检查所有任务是否完成。

1. 创建并配置线程池

使用 Executors类创建一个合适的线程池。以下示例使用固定大小的线程池。

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

ExecutorService executorService = Executors.newFixedThreadPool(10);
​
   

2. 提交异步任务

将多个异步任务提交到线程池。这里使用简单的示例任务进行演示。

import java.util.concurrent.Callable;

for (int i = 0; i < 20; i++) {
    final int taskId = i;
    executorService.submit(new Callable<Void>() {
        @Override
        public Void call() throws Exception {
            System.out.println("Executing task " + taskId);
            Thread.sleep(1000);  // 模拟任务执行时间
            System.out.println("Task " + taskId + " completed");
            return null;
        }
    });
}
​
   

3. 使用 CompletionService监控任务完成情况

CompletionService可以将任务的提交与完成分离,使我们能够方便地监控任务的完成情况。

import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorCompletionService;

CompletionService<Void> completionService = new ExecutorCompletionService<>(executorService);
​
   

4. 实现异步检查任务完成

可以使用一个单独的线程来异步检查所有任务是否完成。当所有任务完成后,执行相应的操作。

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

Runnable checkCompletion = new Runnable() {
    @Override
    public void run() {
        int completedTaskCount = 0;
        while (completedTaskCount < 20) {
            try {
                Future<Void> future = completionService.take(); // 阻塞等待下一个任务完成
                future.get(); // 获取任务结果,确保任务没有抛出异常
                completedTaskCount++;
                System.out.println("Completed tasks: " + completedTaskCount);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println("All tasks completed.");
    }
};

new Thread(checkCompletion).start();
​
   

完整代码示例

import java.util.concurrent.*;

public class ThreadPoolCompletionChecker {
    public static void main(String[] args) {
        // 创建线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        // 创建CompletionService
        CompletionService<Void> completionService = new ExecutorCompletionService<>(executorService);

        // 提交任务
        for (int i = 0; i < 20; i++) {
            final int taskId = i;
            completionService.submit(new Callable<Void>() {
                @Override
                public Void call() throws Exception {
                    System.out.println("Executing task " + taskId);
                    Thread.sleep(1000);  // 模拟任务执行时间
                    System.out.println("Task " + taskId + " completed");
                    return null;
                }
            });
        }

        // 异步检查所有任务是否完成
        Runnable checkCompletion = new Runnable() {
            @Override
            public void run() {
                int completedTaskCount = 0;
                while (completedTaskCount < 20) {
                    try {
                        Future<Void> future = completionService.take(); // 阻塞等待下一个任务完成
                        future.get(); // 获取任务结果,确保任务没有抛出异常
                        completedTaskCount++;
                        System.out.println("Completed tasks: " + completedTaskCount);
                    } catch (InterruptedException | ExecutionException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("All tasks completed.");
                executorService.shutdown(); // 关闭线程池
            }
        };

        new Thread(checkCompletion).start();
    }
}
​
   

分析说明表

步骤 描述
创建并配置线程池 使用 Executors.newFixedThreadPool创建一个固定大小的线程池。
提交异步任务 使用 submit方法将多个 Callable任务提交到线程池。
使用 CompletionService 创建 ExecutorCompletionService实例来监控任务的完成情况。
异步检查任务完成 使用一个单独的线程异步检查任务的完成情况,通过 CompletionService.take()阻塞等待任务完成,使用 Future.get()确保任务没有抛出异常。

思维导图

Java异步判断线程池任务完成
|
|-- 创建并配置线程池
|   |-- Executors.newFixedThreadPool
|
|-- 提交异步任务
|   |-- submit(Callable)
|
|-- 使用CompletionService
|   |-- ExecutorCompletionService
|
|-- 异步检查任务完成
|   |-- 新建线程
|   |-- CompletionService.take()
|   |-- Future.get()

标签:异步,java,CompletionService,--,任务,线程
From: https://www.cnblogs.com/zzggqq/p/18655024

相关文章

  • ssm在线程序测评系统36lw1--(程序+源码+数据库+调试部署+开发环境)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、研究背景随着计算机科学教育的普及和编程竞赛的兴起,对程序评测的需求日益增长。传统的评测方式受限于时间和地点,难以满足在线教育和竞赛的需求......
  • 咱们一起学 Java(145)
    咱们一起学Java(145)在之前对Java应用程序部署相关知识的学习中,我们已经掌握了JAR文件的创建与使用,以及资源管理和密封机制等重要内容。今天,我们将把重点放在应用程序首选项的存储上,这是提升用户体验的关键环节。用户在使用应用程序时,通常希望能够保存自己的个性化设置和偏......
  • 咱们一起学 Java(144)
    咱们一起学Java(144)在之前对Java应用程序部署中JAR文件的学习里,我们已经了解了如何将应用程序打包成一个方便分发的文件格式。今天,我们将继续深入探讨部署过程中的另外两个重要方面:资源管理和密封。资源管理涉及到如何在应用程序中有效地组织和访问各种数据文件,如图片、文......
  • 咱们一起学 Java(143)
    咱们一起学Java(143)在之前的Java学习旅程中,我们专注于掌握Java语言的特性以及图形编程知识,努力打造功能强大的应用程序。但当应用程序开发完成后,我们面临着一个关键问题:如何将其有效地部署到用户的计算机上?这就引出了我们今天要深入探讨的主题——JAR文件。JAR文件在Java应......
  • 咱们一起学 Java(142)
    咱们一起学Java(142)在之前的学习中,我们已经对Swing程序的调试技巧有了一定的了解,包括查看组件层次结构、使用图形化调试器以及事件跟踪器等。今天,我们将进一步深入实践,结合AWT机器人(Robot)的自动化测试功能,探讨如何更全面、有效地调试和测试Swing程序。通过实际的代码示例和......
  • 聊一聊 C#异步中的Overlapped是如何寻址的
    一:背景1.讲故事前段时间训练营里的一位朋友提了一个问题,我用ReadAsync做文件异步读取时,我知道在Win32层面会传lpOverlapped到内核层,那在内核层回头时,它是如何通过这个lpOverlapped寻找到ReadAsync这个异步的Task的呢?这是一个好问题,这需要回答人对异步完整的运转流程有一......
  • 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-10- 标签页(tab)操作 - 上篇 (详细教
    1.简介本来按照计划这一系列的文章应该介绍Context和Page两个内容的,但是宏哥看了官方文档和查找资料发现其实和宏哥在Python+Playwright系列文章中的大同小异,差不了多少,再在这一个系列介绍就有点画蛇添足,索性就不介绍和讲解了,有兴趣的自己可以看宏哥之前写的,或者自己查找资料和官......
  • Java Spring Boot监听事件和处理事件
    在JavaSpringBoot中,监听事件和处理事件是构建灵活、可扩展应用程序的重要机制。通过事件驱动模型,可以实现组件之间的解耦,增强系统的可维护性和可测试性。本文将详细介绍如何在SpringBoot中监听和处理事件,包括自定义事件的创建、发布和监听。1.自定义事件首先,我们需要创建一......
  • 关于java实现TLS socket的X509自签名证书的一次记录
    创建客户端和服务器端的证书文件通常涉及几个步骤,包括生成私钥、创建证书签名请求(CSR)、签发证书以及将这些信息打包到PKCS#12格式的文件中。以下是详细的步骤说明:1.安装OpenSSL首先,你需要安装OpenSSL,它是一个开源的SSL/TLS工具包,可以用来生成密钥对和证书。Windows:可以从......
  • window环境运行 django+celery+redis 异步任务报错:kombu.exceptions.OperationalError
    在所有配置都正常,并且redis服务正常,django和celery服务启动都正常;但就在请求执行异步任务时报错了:kombu.exceptions.OperationalError:[WinError10061]由于目标计算机积极拒绝,无法连接。启动服务指令:django:pythonmanage.pyrunservercelery:celery-Adifyworker-l......