Fre*_*ind 5 java executorservice fork-join
我在Java 7中阅读了一篇关于fork-join框架的精彩文章,其思想是,使用ForkJoinPool和ForkJoinTask,池中的线程可以从其他任务中获取子任务,因此它可以使用更少的线程来处理更多任务.
然后我尝试使用法线ExecutorService来做同样的工作,发现我无法区分,因为当我向池中提交新任务时,任务将在另一个可用线程上运行.
我能说的唯一区别是,如果我使用ForkJoinPool,我不需要将池传递给任务,因为我可以调用task.fork()它使其在另一个线程上运行.但是正常情况下ExecutorService,我必须将池传递给任务,或者使它成为静态,所以在任务中,我可以调用pool.submit(newTask)
我错过了什么吗?
(您可以从https://github.com/freewind/fork-join-test/tree/master/src查看生活代码)
虽然是ForkJoinPool实现ExecutorService,但它在概念上与"普通"执行器不同.
如果您的任务产生更多任务并等待它们完成,您可以轻松地看到差异,例如通过调用
executor.invoke(new Task()); // blocks this thread until new task completes
Run Code Online (Sandbox Code Playgroud)
在正常执行程序服务中,等待其他任务完成将阻止当前线程.有两种可能的结果:如果执行程序服务具有固定数量的线程,则如果最后一个正在运行的线程等待另一个任务完成,则可能会死锁.如果您的执行程序根据需要动态创建新线程,则线程数可能会爆炸,并且最终会有数千个可能导致饥饿的线程.
相反,fork/join框架在此期间重用该线程来执行其他任务,因此尽管线程数是固定的,它也不会死锁:
new MyForkJoinTask().invoke();
Run Code Online (Sandbox Code Playgroud)
因此,如果您遇到可以递归求解的问题,请考虑使用a,ForkJoinPool因为您可以轻松实现一级递归ForkJoinTask.
只需检查示例中正在运行的线程数.
| 归档时间: |
|
| 查看次数: |
1231 次 |
| 最近记录: |