java中有三种不同的多线程技术- Fork/Join pool, Executor Service &CountDownLatch
Fork/Join pool (http://www.javacodegeeks.com/2011/02/java-forkjoin-parallel-programming.html)
Fork/Join框架旨在使分治算法易于并行化。这种类型的算法对于可以分为两个或多个相同类型的子问题的问题是完美的。他们使用递归将问题分解为简单的任务,直到这些任务变得足够简单,可以直接解决。然后将子问题的解组合起来,给出原始问题的解
ExecutorService是一个扩展Executor类的接口,表示异步执行。它为我们提供了管理异步任务结束和检测异步任务进程的机制。
invokeAll():执行给定的任务,返回一个future列表,其中包含所有任务完成后的状态和结果。Future.isDone()对返回列表中的每个元素都为true。
CountDownLatch : (http://examples.javacodegeeks.com/core-java/util/concurrent/countdownlatch-concurrent/java-util-concurrent-countdownlatch-example/)
CountDownLatch用于同步,允许一个或多个线程等待,直到其他线程执行的一组操作完成。
我的假设:
在这两种选择中,只有在所有任务/线程完成后才知道最终结果。
这三个选项是互补的还是互为补充的 ?
经过对各种多线程框架的研究,我从各种oracle文档页面中找到了问题的答案
ExecutorService
使用简单,控制有限。
当Callable/Runnable
任务数量较少并且在无界队列中堆积任务不会导致内存堆积时,我更喜欢这个&降低系统性能
它隐藏了ThreadPoolExecutor
的低层细节。它不允许在ThreadPoolExectuor
中使用其他参数(Bounded Queue, Rejection Handler
等来微调性能)。
ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime,
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
它为您提供了更多的控制。除了设置最小和最大线程,您还可以设置队列大小并使BlockingQueue
是有界的。
如果你的应用程序受到挂起的可运行/可调用任务数量的限制,你将通过设置最大容量来使用有界队列。一旦队列达到最大容量,您就可以定义RejectionHandler。Java提供四种类型的拒绝处理程序策略。
CountDownLatch
CountDownLatch
:这个框架允许java线程等待其他线程完成它们的任务。
ForkJoinPool
ForkJoinPool
与Java ExecutorService类似,但有一点不同。
当大多数任务产生其他子任务时(就像大多数ForkJoinTasks一样),以及当许多小任务从外部客户端提交到池时,这使得有效的处理成为可能
public ForkJoinPool(int parallelism,
ForkJoinPool.ForkJoinWorkerThreadFactory factory,
Thread.UncaughtExceptionHandler handler,
boolean asyncMode)
关于主查询:
您可以使用ExecutorService.invokeAll()
或CountDownLatch
框架或ForkJoinPool
。所有这些框架都是相互补充的,通过粒度的变化来控制从高层到低层的任务执行。
查看相关SE问题:
使用ExecutorService的优点是什么?
Java's Fork/Join vs ExecutorService -何时使用哪个?