java Fork/Join池,ExecutorService和CountDownLatch

Rav*_*abu 1 java multithreading executorservice countdownlatch forkjoinpool

我们在java中有三种不同的多线程技术 - 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用于同步,以允许一个或多个线程等待,直到在其他线程中执行的一组操作完成.

我的假设:

在这两种替代方案中,只有在完成所有任务/线程后才能知道最终结果.

这三种选择是互补的还是互补的

Rav*_*abu 8

在研究过去3个月的各种多线程框架之后,我找到了问题的答案.

ExecutorService的

它控制有限,简单易用.你可以使用它

  1. 在没有等待的情况下启动并行独立任务
  2. 等待所有任务完成

Callable/Runnable任务数量很少而且无限制队列中的任务堆积不会导致内存堆积并降低系统性能时,我更喜欢这个.

它隐藏了低级细节ThreadPoolExecutor.它不允许使用其他参数(Bounded Queue, Rejection Handler等等来微调性能),如同ThreadPoolExectuor.

的ThreadPoolExecutor

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, 
TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
Run Code Online (Sandbox Code Playgroud)

它为您提供更多控制.除了设置最小和最大线程外,您还可以设置队列大小并使其BlockingQueue有界.

如果您需要以下功能,可以提供自己的线程工厂

  1. 设置更具描述性的线程名称
  2. 设置线程守护程序状态
  3. 设置线程优先级

如果您的应用程序受到待处理的Runnable/Callable任务数量的限制,您将通过设置最大容量来使用有界队列.队列达到最大容量后,您可以定义RejectionHandler.Java提供了四种类型的拒绝处理程序策略.

  1. 在默认情况下ThreadPoolExecutor.AbortPolicy,处理程序在拒绝时抛出运行时RejectedExecutionException.

  2. ThreadPoolExecutor.CallerRunsPolicy,调用execute本身的线程运行任务.这提供了一种简单的反馈控制机制,可以降低新任务的提交速度.

  3. ThreadPoolExecutor.DiscardPolicy,简单地删除无法执行的任务.

  4. ThreadPoolExecutor.DiscardOldestPolicy,如果执行程序未关闭,则删除工作队列头部的任务,然后重试执行(可能再次失败,导致重复执行).

CountDownLatch

CountDownLatch :此框架允许java线程等待,直到其他线程集完成其任务.

用例:

  1. 实现最大并行性:有时我们希望同时启动多个线程以实现最大并行度

  2. 在开始执行其他代码块之前等待N个线程完成

  3. 死锁检测.

本文列出了更多详细信息

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.
Run Code Online (Sandbox Code Playgroud)

参数:

并行性 - 并行性水平.对于默认值,请使用Runtime.availableProcessors().

factory - 用于创建新线程的工厂.对于默认值,请使用defaultForkJoinWorkerThreadFactory.

handler - 由于不可恢复的错误而终止的内部工作线程的处理程序

asyncMode - 如果为true,则为从未加入的分叉任务建立本地先进先出调度模式.

关于主要查询:

你可以使用ExecutorService.invokeAll()CountDownLatch框架或ForkJoinPool.所有这些框架彼此互补,具有不同的粒度,以控制任务从高级别到低级别的执行.

编辑:

看看相关的SE问题:

使用ExecutorService有什么好处?

Java的Fork/Join vs ExecutorService - 何时使用哪个?