在过去三个月对各种多线程框架进行研究之后,我找到了问题的答案。
执行器服务
它简单易用,控制范围有限。你可以用
- 在不等待的情况下启动并行独立任务
- 等待所有任务完成
当
Callable/Runnable任务数量很少且无边界队列中的任务堆积不会导致内存堆积并降低系统性能时,我更喜欢这种方法。
它隐藏了的低级详细信息
ThreadPoolExecutor。不允许使用中的其他参数(
Bounded Queue, RejectionHandler等来微调演奏)
ThreadPoolExectuor。
线程池执行器
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory,RejectedExecutionHandler handler)
它为您提供更多控制。除了设置最小和最大线程外,您还可以设置队列大小和make
BlockingQueue有界。
如果需要以下功能,可以提出自己的线程工厂
- 设置更具描述性的线程名称
- 设置线程守护程序状态
- 设置线程优先级
如果您的应用程序受到未决Runnable /
Callable任务数量的限制,则将通过设置最大容量来使用有界队列。一旦队列达到最大容量,就可以定义RejectionHandler。Java提供了四种类型的拒绝处理程序策略。
默认情况下
ThreadPoolExecutor.AbortPolicy
,处理程序在拒绝时抛出运行时RejectedExecutionException。在中
ThreadPoolExecutor.CallerRunsPolicy
,调用执行自己的线程运行任务。这提供了一种简单的反馈控制机制,将降低新任务的提交速度。在中
ThreadPoolExecutor.DiscardPolicy
,简单地删除了无法执行的任务。在中
ThreadPoolExecutor.DiscardOldestPolicy
,如果未关闭执行程序,则将丢弃工作队列开头的任务,然后重试执行(这可能再次失败,从而导致重复执行此操作)。
CountDownLatch
CountDownLatch:此框架允许Java线程等待,直到其他线程集完成其任务。
用例:
实现 最大并行度 :有时我们想同时启动多个线程以实现最大并行度
等待N个线程完成, 然后再开始执行其他代码块
死锁检测。
本文列出了更多详细信息
货叉池
该
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
。所有这些框架都是相互补充的,不同的粒度可以控制从高级到低级任务的执行。
编辑:



