我有N个长整型ID,需要为每个ID执行一个Runnable(即我不关心返回值),并等待所有任务完成。每个Runnable可能需要几秒钟到几分钟的时间,并且可以安全地并行运行约100个线程。
在我们目前的解决方案中,我们使用Executors.newFixedThreadPool(),对每个ID调用submit(),然后在每个返回的Future上调用get()。
这段代码工作得很好,而且非常简单,因为我不必处理线程、复杂的等待逻辑等。它的缺点是内存占用。
所有仍在排队的Runnable占用内存(比long需要的8个字节多得多:这些是我的Java类,具有一些内部状态),所有N个Future实例也会占用内存(这些也是带有状态的Java类,我只用于等待但不需要实际结果)。我查看了堆转储,估计10百万时占用了略大于1 GiB的内存。如果将10百万个long存储在数组中,只需要76 MiB的内存。
是否有一种方法可以仅保留内存中的ID来解决此问题,最好不要使用低级并发编程?
在我们目前的解决方案中,我们使用Executors.newFixedThreadPool(),对每个ID调用submit(),然后在每个返回的Future上调用get()。
这段代码工作得很好,而且非常简单,因为我不必处理线程、复杂的等待逻辑等。它的缺点是内存占用。
所有仍在排队的Runnable占用内存(比long需要的8个字节多得多:这些是我的Java类,具有一些内部状态),所有N个Future实例也会占用内存(这些也是带有状态的Java类,我只用于等待但不需要实际结果)。我查看了堆转储,估计10百万时占用了略大于1 GiB的内存。如果将10百万个long存储在数组中,只需要76 MiB的内存。
是否有一种方法可以仅保留内存中的ID来解决此问题,最好不要使用低级并发编程?
Long
参数的Runnable
,并且让您的Runnable
将该长整型转换为具有内部状态的自定义Java类?这将降低可运行队列的占用空间,并通过使它们中没有任何一个保留您的“内部状态”,从而降低Future
的占用空间。一句话:将重量级状态的创建推迟到可运行内部。 - GPI