先说结论:Future集合并不是等线程池执行完才开始遍历,而是线程池内的线程执行完一条Future集合就立即遍历一条


在使用线程池的业务场景下,我们经常需要获取线程执行的返回值,此时我们需要Callable对象当做线程池参数并用List<Future>接收,然后遍历List<Future>获取我们想要的值。

但是,如果List<Future>是等线程池中所有的线程执行完后才开始遍历,就意味着List集合可能会非常大,进而导致内存溢出程序崩溃。所以我们就来验证一下List<Future>是会等待线程池执行完毕开始遍历还是只要线程执行完一条就遍历一条

示例:

ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 5, 60L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
List<Future<Integer>> futureList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
int finalI = i;
Future<Integer> future = executor.submit(() -> {
Thread.sleep(1000L);
System.out.println(Thread.currentThread().getName() + " " + finalI);
return finalI;
});
futureList.add(future);
}
System.out.println("futureList.size() = "+futureList.size());
Iterator<Future<Integer>> iterator = futureList.iterator();
while (iterator.hasNext()) {
Integer i = iterator.next().get();
iterator.remove();
System.out.println("执行后 " + i);
//业务代码......
}

执行结果:

由此足以证明List<Future>集合不会等待线程池执行完才开始遍历,只要我们在遍历后把元素删除就能一定程度避免List<Future>过大导致内存溢出。

注意这里说的是一定程度,并不能完全避免,这取决于“业务代码”的执行时长,如果上面线程池都执行完了,下面一个业务都没处理完,同样会导致List<Future>占用很多内存,所以业务代码尽量放到上面的线程池里面。

当然如果能确定List<Future>不会很大导致内存溢出放到下面遍历自然更加优美,还请根据实际业务情况抉择。

Future集合会等线程池执行完才开始遍历吗?的更多相关文章

  1. ThreadPoolExecutor源码分析-面试问烂了的Java线程池执行流程,如果要问你具体的执行细节,你还会吗?

    Java版本:8u261. 对于Java中的线程池,面试问的最多的就是线程池中各个参数的含义,又或者是线程池执行的流程,彷佛这已成为了固定的模式与套路.但是假如我是面试官,现在我想问一些更细致的问题, ...

  2. Java 使用线程池执行若干任务

    在执行一系列带有IO操作(例如下载文件),且互不相关的异步任务时,采用多线程可以很极大的提高运行效率.线程池包含了一系列的线程,并且可以管理这些线程.例如:创建线程,销毁线程等.本文将介绍如何使用Ja ...

  3. 捕获Java线程池执行任务抛出的异常

    捕获Java线程池执行任务抛出的异常Java中线程执行的任务接口java.lang.Runnable 要求不抛出Checked异常, public interface Runnable { publi ...

  4. CountDownLatch用法---等待多个线程执行完才执行

    CountDownLatch用法---等待多个线程执行完才执行 CountDownLatch用法---等待多个线程执行完才执行 CountDownLatch用法---等待多个线程执行完才执行 Coun ...

  5. ScheduledThreadPoolExecutor 使用线程池执行定时任务

    转自:https://segmentfault.com/a/1190000008038848 在现实世界里,我们总是免不了要定期去做一件事情(比如上课)—— 在计算机的世界里,更是如此.比如我们手机每 ...

  6. spring boot使用自定义配置的线程池执行Async异步任务

    一.增加配置属性类 package com.chhliu.springboot.async.configuration; import org.springframework.boot.context ...

  7. java 多线程 线程池:多核CPU利用ExecutorService newWorkStealingPool; ForkJoinPool线程池 执行可拆分的任务RecursiveAction;RecursiveTask

    1,给定并行级别: 1,ExecutorService newWorkStealingPool(int parallelism): 创建持有足够的线程的线程池来支持给定的并行级别,该方法还会使用多个队 ...

  8. 对象回收过程?线程池执行过程? map原理?集合类关系?synchronized 和 volatile ? 同一个类的方法事务传播控制还有作用吗?java 锁

    1.  对象回收过程? 可达性分析算法: 如果一个对象从 GC Roots 不可达时,则证明此对象不可用. 通过一系列称为GC ROOTS的对象作为起点,从这些起点往下搜索,搜索走过的路径 称为引用链 ...

  9. IntentService 串联 按顺序执行(此次任务执行完才执行下一个任务)

    IntentService与Service的最大区别就是前者依次执行,执行完当前任务才执行下一个任务,后者并发执行 在IntentService里面不写onCreate方法 MainActivity: ...

  10. Java 中的几种线程池这么用才是对的

    为什么要使用线程池 虽然大家应该都已经很清楚了,但还是说一下.其实归根结底最主要的一个原因就是为了提高性能. 线程池和数据库连接池是同样的道理,数据库连接池是为了减少连接建立和释放带来的性能开销.而线 ...

随机推荐

  1. 慢sql治理经典案例分享

    ​简介:菜鸟供应链金融慢sql治理已经有一段时间,自己负责的应用持续很长时间没有慢sql告警,现阶段在推进组内其他成员治理应用慢sql.这里把治理过程中的一些实践拿出来分享下. ​ 作者 | 如期 来 ...

  2. Dapr 在阿里云原生的实践

    简介: Faas 场景下,比较吸引用户的是成本和研发效率,成本主要通过按需分配和极致的弹性效率来达成.而应用开发者期望通过 FaaS 提供多语言的编程环境,提升研发效率,包括启动时间.发布时间.开发的 ...

  3. [PHP] 有关PHP浮点数默认显示位数 precision 以及如何调整

    PHP 以浮点数显示的有效位数默认是 14 位.-1 表示将使用一种增强的算法来四舍五入这些数字. 如果想显示更长的浮点位数,可以设置如:ini_set('precision', 40); 有两点需要 ...

  4. WPF 获取全局所有窗口的创建显示事件 监控窗口打开

    本文将告诉大家如何在 WPF 里面进行全局监控任意的窗口创建显示打开,可以获取到每个 WPF 窗口的打开的时机.如此可以用来辅助定位问题和输出日志 这篇博客是有背景的,老司机告诉我说他的应用不响应鼠标 ...

  5. 2018-3-8-WPF-UncommonField-类型是什么

    title author date CreateTime categories WPF UncommonField 类型是什么 lindexi 2018-3-8 16:25:2 +0800 2018- ...

  6. 第一章 Jenkins安装配置

    Jenkins官网 # 官网: https://www.jenkins.iohttps://www.jenkins.io/zh/ # docker安装: https://www.jenkins.io/ ...

  7. Pinely Round 3 (Div. 1 + Div. 2)

    A 构造题,分两种情况考虑 上下都行,左右选一个 左右都行,上下选一个 void solve() { int n; cin >> n; vector<pair<int, int ...

  8. 从SAP CRM上传设备到SAP ERP

    文档<Step by step to download equipment from ERP with hierarchy>描述了从ERP复制设备到CRM的步骤.默认情况下,ERP中的设备 ...

  9. 【web安全】隐藏nginx头文件信息

    摘要 Nginx作为开源web中间件,被广泛应用.因此源编译或者yum安装,都会带有其原有的nginx版本.很容易被针对,因此,通过修改nginx的源码.隐藏nginx版本和头部信息,保障nginx的 ...

  10. gprMax项目代码分解:gprMax.py

    目录 1. 引言 2. 代码分解 (1) 导入模块 (2)main()函数 (3)run_main()函数 (4)run_std_sim()函数 (5)run_benchmark_sim()函数 (6 ...