java Fork / Join池,ExecutorService和CountDownLatch
我们在java中有三种不同的multithreading技术 – Fork / Join池,Executor Service和CountDownLatch
Fork / Join pool ( http://www.javacodegeeks.com/2011/02/java-forkjoin-parallel-programming.html )
Fork / Join框架旨在使分而治之的算法易于并行化。 这种类型的算法非常适合于可以分为两个或更多相同类型的子问题的问题。 他们使用递归将问题分解为简单的任务,直到这些变得足够简单直接解决。 然后组合子问题的解决方案以给出原始问题的解决方案
ExecutorService是一个扩展Executor类并表示异步执行的接口。 它为我们提供了管理结束和检测异步任务进度的机制。
invokeAll() :执行给定的任务,返回一个Futures列表,保存状态和结果全部完成。 Future.isDone()对于返回列表的每个元素都为true。
CountDownLatch 🙁 http://examples.javacodegeeks.com/core-java/util/concurrent/countdownlatch-concurrent/java-util-concurrent-countdownlatch-example/ )
CountDownLatch用于同步,以允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
我的假设:
在这两种替代方案中,只有在完成所有任务/线程后才能知道最终结果。
这三种选择是互补的还是互补的 ?
在对过去3个月的各种multithreading框架进行研究后,我找到了问题的答案。
ExecutorService的
它控制有限,简单易用。 你可以使用它
- 在没有等待的情况下启动并行独立任务
- 等待完成所有任务
当Callable/Runnable
任务的数量很少并且无界队列中的任务堆积不会导致内存堆积并降低系统性能时,我更喜欢这个。
它隐藏了ThreadPoolExecutor
低级细节。 它不允许使用其他参数( Bounded Queue, Rejection Handler
等来微调性能),如ThreadPoolExectuor
。
的ThreadPoolExecutor
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
它为您提供更多控制。 除了设置最小和最大线程,您可以设置队列大小并使BlockingQueue
有界。
如果您需要以下function,可以提供自己的线程工厂
- 设置更具描述性的线程名称
- 设置线程守护程序状态
- 设置线程优先级
如果您的应用程序受到待处理的Runnable / Callable任务数量的限制,您将通过设置最大容量来使用有界队列。 队列达到最大容量后,您可以定义RejectionHandler。 Java提供了四种类型的拒绝处理程序策略 。
-
在默认的
ThreadPoolExecutor.AbortPolicy
,处理程序在拒绝时抛出运行时RejectedExecutionException。 -
在
ThreadPoolExecutor.CallerRunsPolicy
,调用execute本身的线程运行该任务。 这提供了一种简单的反馈控制机制,可以降低新任务的提交速度。 -
在
ThreadPoolExecutor.DiscardPolicy
,简单地删除了无法执行的任务。 -
在
ThreadPoolExecutor.DiscardOldestPolicy
,如果执行程序未关闭,则会删除工作队列头部的任务,然后重试执行(可能会再次失败,导致重复执行)。
CountDownLatch
CountDownLatch
:此框架允许java线程等待,直到其他线程集完成其任务。
用例:
-
实现最大并行性 :有时我们希望同时启动多个线程以实现最大并行度
-
在开始执行其他代码块之前等待N个线程完成
-
死锁检测。
本文列出了更多详细信息
ForkJoinPool
ForkJoinPool
类似于Java ExecutorService,但有一点不同。 ForkJoinPool
使任务可以轻松地将其工作分成较小的任务,然后将这些任务提交给ForkJoinPool。 当忙工作线程从繁忙的工作线程队列中窃取任务时,在ForkJoinPool中发生任务窃取。
public ForkJoinPool(int parallelism, ForkJoinPool.ForkJoinWorkerThreadFactory factory, Thread.UncaughtExceptionHandler handler, boolean asyncMode) Creates a ForkJoinPool with the given parameters.
参数:
并行性 – 并行性水平。 对于默认值,请使用Runtime.availableProcessors()
。
factory – 用于创建新线程的工厂。 对于默认值,请使用defaultForkJoinWorkerThreadFactory。
handler – 由于不可恢复的错误而终止的内部工作线程的处理程序
asyncMode – 如果为true,则为从未加入的分叉任务建立本地先进先出调度模式。
关于主要查询:
您可以使用ExecutorService.invokeAll()
或CountDownLatch
框架或ForkJoinPool
。 所有这些框架彼此互补,具有不同的粒度,以控制任务从高级到低级的执行。
编辑:
看看相关的SE问题:
使用ExecutorService有什么好处?
Java的Fork / Join vs ExecutorService – 何时使用哪个?