java-以较小的内存占用空间执行数百万个Runnable
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java-以较小的内存占用空间执行数百万个Runnable,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2388字,纯文字阅读大概需要4分钟。
内容图文
![java-以较小的内存占用空间执行数百万个Runnable](/upload/InfoBanner/zyjiaocheng/949/5a33226bbe0048178549f5e74536190f.jpg)
我有N个身份证.对于每个ID,我都需要执行一个Runnable(即,我不在乎返回值),并等到所有它们都完成为止.每个Runnable可能需要花费几秒钟到几分钟的时间,并行运行大约100个线程是安全的.
在当前解决方案中,我们使用Executors.newFixedThreadPool(),为每个ID调用Submit(),然后在每个返回的Future上调用get().
该代码运行良好,并且非常简单,因为我不必处理线程,复杂的等待逻辑等.它有一个缺点:内存占用量.
所有仍然排队的Runnable的内存消耗(比很长的内存要多8个字节:这是我的Java类,带有某些内部状态),并且所有N Future实例也都占用内存(这些都是具有状态的Java类) ,我仅用于等待,但不需要实际结果).我查看了一个堆转储,我估计N = 1000万将占用1 GiB以上的内存.阵列中的1000万长仅消耗76 MiB.
是否有办法仅通过将ID保留在内存中来解决此问题,最好不采用低级并发编程?
解决方法:
这是我通常使用Producer / Consummer模式和一个BlockingQueue协调两者的事情,或者如果我手头有项目,则使用Akka actor.
但是我认为我建议依靠Java的Stream行为来解决一些问题.
直觉是,流的延迟执行将用于限制工作单元,期货及其结果的创建.
public static void main(String[] args) {
// So we have a list of ids, I stream it
// (note : if we have an iterator, you could group it by a batch of, say 100,
// and then flat map each batch)
LongStream ids = LongStream.range(0, 10_000_000L);
// This is were the actual tasks will be dispatched
ExecutorService executor = Executors.newFixedThreadPool(4);
// For each id to compute, create a runnable, which I call "WorkUnit"
Optional<Exception> error = ids.mapToObj(WorkUnit::new)
// create a parralel stream
// this allows the stream engine to launch the next instructions concurrently
.parallel()
// We dispatch ("parallely") the work units to a thread and have them execute
.map(workUnit -> CompletableFuture.runAsync(workUnit, executor))
// And then we wait for the unit of work to complete
.map(future -> {
try {
future.get();
} catch (Exception e) {
// we do care about exceptions
return e;
} finally {
System.out.println("Done with a work unit ");
}
// we do not care for the result
return null;
})
// Keep exceptions on the stream
.filter(Objects::nonNull)
// Stop as soon as one is found
.findFirst();
executor.shutdown();
System.out.println(error.isPresent());
}
老实说,我并不确定要确保该行为由规范来保证,但是根据我的经验,它是可行的.并行的“块”中的每一个都获取一些ID,将其馈送到管道(映射到工作单元,调度到线程池,等待结果,过滤异常),这意味着可以很快达到平衡平衡有效工作单位与执行者的数量.
如果要微调并行“块”的数量,请在此处跟进:Custom thread pool in Java 8 parallel stream
内容总结
以上是互联网集市为您收集整理的java-以较小的内存占用空间执行数百万个Runnable全部内容,希望文章能够帮你解决java-以较小的内存占用空间执行数百万个Runnable所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。