并发任务管理:`submit()` 和 `invokeAll()` 的对比

ops/2025/1/23 16:35:43/

并发任务管理:submit()invokeAll() 的对比

在 Java 中,使用多线程执行并发任务是提高性能的常用手段。本文将深入探讨 submit()invokeAll() 的使用场景、执行方式及其优缺点,并通过示例和对比帮助理解如何在实际开发中选择合适的方法。


1. submit() 方法

submit() 方法是 ExecutorService 提供的基础任务提交方式,可以提交单个任务并返回一个 Future 对象用于异步获取结果。主线程可以根据需求调用 Future.get() 来获取任务结果,也可以选择不立即处理结果。

特性
  1. 异步任务提交:提交任务后,主线程可以继续执行其他逻辑。
  2. 灵活的任务控制:可以单独处理任务的结果、异常等。
  3. 支持动态任务:任务可以在运行时动态添加。
示例
java">ExecutorService executor = Executors.newFixedThreadPool(3);Future<String> future1 = executor.submit(() -> {Thread.sleep(5000); // 模拟耗时任务return "任务1完成";
});
Future<String> future2 = executor.submit(() -> {Thread.sleep(2000);return "任务2完成";
});// 主线程继续执行其他逻辑
System.out.println("主线程执行中...");// 按需获取任务结果
try {System.out.println(future1.get()); // 等待任务1完成System.out.println(future2.get()); // 等待任务2完成
} catch (InterruptedException | ExecutionException e) {e.printStackTrace();
}executor.shutdown();
优点
  • 提交任务后主线程可以继续执行,无需阻塞等待。
  • 支持动态任务的添加。
  • 对任务的结果和异常可以单独处理,灵活性高。
缺点
  • 如果多个任务结果需要按顺序调用 get(),可能会导致总耗时等于所有任务耗时的累加值(非最优)。
  • 需要开发者自行管理任务间的关系和依赖。

2. invokeAll() 方法

invokeAll()ExecutorService 提供的一种批量任务提交方法,一次性提交一组任务,并阻塞直到所有任务完成。它返回一个包含所有 Future 对象的列表,任务结果可以逐个获取。

特性
  1. 批量提交:一次性提交多个任务。
  2. 并行执行:任务由线程池并行执行。
  3. 统一阻塞:调用 invokeAll() 后主线程会阻塞,直到所有任务完成。
示例
java">ExecutorService executor = Executors.newFixedThreadPool(3);List<Callable<String>> tasks = new ArrayList<>();
tasks.add(() -> {Thread.sleep(5000);return "任务1完成";
});
tasks.add(() -> {Thread.sleep(2000);return "任务2完成";
});
tasks.add(() -> {Thread.sleep(3000);return "任务3完成";
});// 执行所有任务并获取结果
try {List<Future<String>> futures = executor.invokeAll(tasks);// 获取任务结果for (Future<String> future : futures) {System.out.println(future.get());}
} catch (InterruptedException | ExecutionException e) {e.printStackTrace();
}executor.shutdown();
优点
  • 简化了批量任务的提交和管理,适合一次性完成多个任务的场景。
  • 任务执行是并行的,总耗时等于耗时最长的任务,而不是累加。
缺点
  • 主线程在调用 invokeAll() 时会阻塞,无法继续执行其他逻辑。
  • 任务结果的获取是整体的,缺乏对单个任务灵活的控制。

3. 使用对比

特性submit()invokeAll()
任务提交方式单个任务提交,返回 Future批量任务提交,返回 Future 列表
执行模式异步阻塞直到所有任务完成
灵活性高,支持动态添加任务和单独结果处理较低,一次性批量提交,统一阻塞
耗时管理逐一调用 get() 可能累加耗时总耗时等于耗时最长的任务
异常处理可以逐一处理任务的异常统一抛出异常,需后续处理
适用场景动态任务、异步处理、任务间有优先级批量任务、一致性处理

4. 实际应用场景

适合使用 submit() 的场景
  1. 任务数量不确定,需在运行时动态添加。
  2. 主线程需要在等待任务结果之前继续执行其他逻辑。
  3. 任务结果的重要性不同,需要按优先级处理。

示例:按优先级处理任务

java">Future<String> importantTask = executor.submit(() -> performImportantTask());
Future<String> lessImportantTask = executor.submit(() -> performLessImportantTask());// 优先处理重要任务
System.out.println("重要任务结果: " + importantTask.get());
System.out.println("次要任务结果: " + lessImportantTask.get());
适合使用 invokeAll() 的场景
  1. 任务数量固定,一次性完成所有任务。
  2. 所有任务的重要性和优先级相同。
  3. 希望简化任务管理,而不关心任务的动态性或灵活性。

示例:批量处理固定任务

java">List<Callable<String>> fixedTasks = Arrays.asList(() -> taskA(),() -> taskB(),() -> taskC()
);
executor.invokeAll(fixedTasks);

5. 总结

在选择 submit()invokeAll() 时,应根据具体场景权衡任务管理的灵活性和效率:

  • 灵活性优先:如果任务需要动态提交、分步处理或按优先级管理,选择 submit()
  • 效率优先:如果任务数量固定,且希望一次性完成所有任务,选择 invokeAll()

两者并无绝对优劣,而是各有侧重。理解各自的特性和适用场景,可以更高效地实现并发任务的管理和执行。


http://www.ppmy.cn/ops/152505.html

相关文章

机器学习练习day1

使用scikit-learn中的KNN包实现对鸢尾花数据集或者自定义数据集的的预测 KNN算法有三要素&#xff1a;1.K值选择&#xff1b;2.距离选择&#xff1b;3.分类规则选择。 步骤1 导入数据集 步骤2 将数据集设置标签 步骤3 设置超参数 代码 from sklearn.neighbors import KNei…

Dart语言的云计算

Dart语言在云计算中的应用与发展 引言 随着云计算技术的迅猛发展&#xff0c;越来越多的开发者和企业开始关注如何利用云计算实现更高效的应用程序开发。在众多编程语言中&#xff0c;Dart语言因其独特的特性与优势&#xff0c;逐渐成为云计算开发领域中的一种热门选择。本文…

【深度学习基础】多层感知机 | 多层感知机的实现

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上&#xff0c;结合当代大数据和大算力的发展而发展出来的。深度学习最重…

【C++提高篇】—— C++泛型编程之模板基本语法和使用的详解

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、模板的概念二、函数模板2.1 函数模板的使用2.2 函数模板注意事项2.3 普通函数与函数模板的区别2.4 普通函数与函数模板的调用规则2.5 模板的局限性 三、类模…

H3C-防火墙IPSec配置案例(主模式)

目录 1.IPSec简述:2.IPSec应用场景:3.网络拓扑及说明:4.案例背景:5.网络配置:5.1 基础网络配置:5.1.1 总部防火墙基础配置:5.1.2 分部防火墙基础配置:5.1.3 互联网路由器基础配置:5.1.4 总部服务器基础配置:5.1.5 总部PC基础配置: 5.2 IPSec配置:5.2.1 总部防火墙IPSec配置:5.2…

MySQL用户授权、收回权限与查看权限

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

gitlabgit分支合并

在GitLab中&#xff0c;分支合并是一个非常常见的操作&#xff0c;可以将一个分支的改动合并到另一个分支中。下面我将为你介绍一下GitLab中分支合并的具体步骤。 首先&#xff0c;进入你的项目仓库页面&#xff0c;在页面上方的导航栏中点击”Repository”&#xff0c;然后选择…

2025年——【寒假】自学黑客计划(网络安全)

CSDN大礼包&#xff1a;&#x1f449;基于入门网络安全/黑客打造的&#xff1a;&#x1f449;黑客&网络安全入门&进阶学习资源包 前言 什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&…