【发布时间】:2019-02-04 10:08:03
【问题描述】:
我有 N 个作为 ID 的 long。对于每个 ID,我需要执行一个 Runnable(即,我不关心返回值)并等待它们全部完成。每个 Runnable 可能需要几秒钟到几分钟的时间,并行运行大约 100 个线程是安全的。
在我们当前的解决方案中,我们使用 Executors.newFixedThreadPool(),为每个 ID 调用 submit(),然后在每个返回的 Future 上调用 get()。
代码运行良好,而且非常简单,我不必处理线程、复杂的等待逻辑等。它有一个缺点:内存占用。
所有仍在排队的 Runnable 消耗内存(比 long 所需的多 8 个字节:这些是我的 Java 类具有一些内部状态),所有 N 个 Future 实例也消耗内存(这些是 Java 类状态也是如此,我只用于等待,但我不需要实际结果)。我查看了一个堆转储,我估计 N=1000 万会占用超过 1 GiB 的内存。数组中的 1000 万个 long 只会消耗 76 MiB。
有没有办法解决这个问题,只将 ID 保存在内存中,最好不求助于低级并发编程?
【问题讨论】:
-
您只需要生成例如10k Runnables 并将它们提交给 executor,一旦完成一半,再生成 5k,依此类推。
-
有没有办法只提交一个
Runnable包装你的Long参数,并让你的Runnable将那么长的时间转换为具有内部状态的自定义 java 类?这将降低可运行队列的占用空间,并降低Futures 的占用空间,因为它们中的任何一个都不会保留您的“内部状态”。一句话:将重量级状态的创建推迟到 runnable 内部。 -
@GPI 会有所帮助,但空对象的开销是 16 个字节,所以仍然很多。
-
“我有 N 个多头” - 以什么形式?在文件中,还是在服务器中?
标签: java multithreading