java - 执行器服务和巨大的IO

标签 java multithreading concurrency executorservice

我有一个服务调用数据库并对每个结果执行回调。

ExecutorService service = Executors.newFixedThreadPool(10);
service.exectute(runnable(segmentID, callback)); // database is segmented

可运行的是:

call database - collect all the rows for the segment keep in memory
perform callback(segment);

现在的问题是我收到数据库返回的大量行,我的理解是执行器服务将在 I/O 空闲时调度线程。所以我进入了“内存不足”状态。

有没有办法限制一次只运行10个线程,并且不发生执行器服务调度?

出于某种原因,我必须将段的所有行保留在内存中。 我怎样才能通过这样做来防止 OOM。 Executor 服务 newFixedThreadPool 是否可以解决此问题?

如果我错过了什么,请告诉我。

谢谢

最佳答案

您必须使用固定线程池。有一条规则,您应该只生成 N 个线程,其中 N 的数量级应该与 CPU 中的核心数量相同。关于 N 的大小存在争议,您可以阅读更多相关内容 here 。对于普通 CPU,我们可以讨论 4、8、16 个线程。

但是,即使您在集群中运行程序(我认为您不是),您也不能只从数据库中获取 20k 行并假装生成 20k 线程。如果这样做,应用程序的性能将会大幅下降,因为大部分 CPU 周期将消耗在上下文切换中。

现在,即使使用固定的线程池,如果获取的数据同时存储在内存中,您也可能会遇到 OOM 异常。我认为唯一的解决方案是获取较小的数据 block ,或者在下载数据时将数据写入文件。

关于java - 执行器服务和巨大的IO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33186187/

相关文章:

windows - 如何将 SetThreadAffinityMask 与 QueryPerformanceFrequency 一起使用?

concurrency - 如何在 Jmeter 中生成并发用户负载

java - JVM 在桌面 Libgdx 应用程序中因非法指令而崩溃

java - 如何在条目顺序不断变化时比较两个 JSON 字符串

java - 单元测试框架 - TestNG 使用可配置值来定义 threadPoolSize

java - 在 ScheduledThreadPoolExecutor 中终止之前等待任务完成

asp.net - 限制并发还是不限制并发? (在单个 ASP.NET 请求内)

java - 了解工作文件上传解决方案

java - 分数++不起作用

c++ - 线程池C++实现问题