java 重用执行器
我研究一个模拟系统,在每个时间步,我必须模拟许多模型。我使用了固定线程池来加速计算:
ExecutorService executor = Executors.newFixedThreadPool(nThread);
for (Model m : models) {
executor.execute( m.simulationTask() );
}
executor.shutdown();
while ( ! executor.awaitTermination(10, TimeUnit.MINUTES) ) {
System.out.println("wait");
}
现在,调用 shutdown()
后,执行器不能用于 execute()
新任务。有没有办法重置执行器,以便我可以在下一个模拟步骤中重用现有的执行器(及其线程)?
I work on a simulation system, where at each timestep, I have to simulate many models. I used a FixedThreadPool to speed up the calculation:
ExecutorService executor = Executors.newFixedThreadPool(nThread);
for (Model m : models) {
executor.execute( m.simulationTask() );
}
executor.shutdown();
while ( ! executor.awaitTermination(10, TimeUnit.MINUTES) ) {
System.out.println("wait");
}
Now, the executor can't be used to execute()
new Tasks after calling shutdown()
. Is there a way to reset the executor, so I can reuse the existing executor (and its threads) at the next simulation step?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您稍微重构一下代码,您可以重用执行程序服务。
基本上,您收集所有任务,执行它们,并在继续之前等待执行。当然,您也可以为每个时间步骤使用新的执行器服务,但至少您有选择。
注意事项:我没有编译代码,因此可能会出现错误。为了方便起见,我还假设了 Integer 参数类型。
You can reuse the executor service if you restructure your code somewhat.
Basically you collect all your tasks, execute them, and await execution before proceeding. Of course, you could also alternatively just use a new Executor Service for each of your time steps, but at least you have options.
Caveats: I didn't compile the code so there might be errors. I also assumed an Integer parameter type for convenience.
您可以编写自己的 Executor 接口实现。除此之外,我知道的大多数默认实现都会在 shutdown() 之后进行内存清理,因此没有(据我所知)预先制定的解决方案。
考虑到
shutdown()
可能会进行大量清理和垃圾收集,目前尚不清楚为什么重新启动会比获取新的Executor
更好,也许您应该看看进入教程 关于使用暂停/恢复方法集扩展 ThreadPoolExecutor,而不是添加取消关闭的功能。You can write your own implementation of the
Executor
interface. Beyond that, most of the default implementation that I am aware of reap threads and do memory cleanup aftershutdown()
, so there is no (to my knowledge) pre-made solution.Considering that
shutdown()
is likely to do a lot of cleanup and garbage collection, it's not exactly clear why restarting would be better than accquiring a newExecutor
, perhaps you should look into the tutorials about extendingThreadPoolExecutor
with a pause / resume set of methods instead of adding the ability to un-shutdown.将您的 ExecutorService 声明为成员您的课程并根据需要重用它。不要对其调用 shutdown(),因为它将不再接受任何任务。当然,你的任务应该很好地结束,并且它们也应该在某个时刻终止。
Declare your ExecutorService as a member to your class and reuse it as you want. Do not call shutDown() on it as it will not accept any more tasks. Of course your tasks should end nicely and they also should terminate at some point.
只需获取另一个 ExecutorService 即可。无论如何,开销是最小的。
如果你坚持重用同一个执行器,你可以实现自己的屏障机制。提交新任务后,自动递增计数器。当任务完成时,自动递减计数器。在主线程中等待,直到计数器为零。类似于:
然后在任务的
run
中:Just acquire another
ExecutorService
. The overhead is minimal anyway.If you insist on reusing the same executor, you can implement your own barrier mechanism. Upon submitting a new task, atomically increment a counter. When a task finishes, atomically decrement the counter. In the main thread wait until the counter is zero. Something like:
Then inside the
run
of your tasks: