@tenlee
2018-12-08T16:29:07.000000Z
字数 2146
阅读 2982
Java
Spring
ExecutorService
和TaskExecutor
都是使用线程池来管理多线程异步执行任务,他们有什么关联和区别,什么时候该用哪个呢?
ExecutorService
是一个提供管理终止的方法和可以生成Future的方法的Executor
,用于跟踪一个或多个异步任务的进度(AnExecutor
that provides methods to manage termination and methods that can produce aFuture
for tracking progress of one or more asynchronous tasks.)。
关闭ExecutorService
会导致它拒绝新的任务,提供了两种不同的方法来关闭ExecutorService
。shutdown()
方法将允许之前已经提交的任务执行完毕后再挂很关闭,而shutdownNow()
方法则阻止正在等待的任务启动并尝试停止当前正在执行的任务。终止时,执行程序没有正在执行的任务,没有等待执行的任务,也没有任何新任务可以提交。应关闭未使用的ExecutorService以允许回收其资源。
基于Executor.execute(Runnable)
的扩展的方法submit
可以创建和返回可用于取消执行和/或等待完成的Future
。invokeAny
和invokeAl
是常用的批量执行任务的方法,执行一组任务,然后等待至少一个或全部完成。
ExecutorService
属于java.util.concurrent
包下面的,继承于java.util.concurrent.Executor
,一般使用java.util.concurrent.Executors
工厂类创建。Executor
和ExecutorService
都是JDK 5
才提供的。
TaskExecutor
用于抽象执行Runnable
的简单任务执行器接口,可以实现使用各种不同的执行策略,例如:同步,异步,使用线程池等。相当于JDK 1.5的Executor
接口;
在Spring 3.0中开始继承Executor
,以便客户可以声明依赖于Executor并接收任何TaskExecutor实现。此接口与标准Executor
接口保持独立,主要是为了在Spring 2.x中向后兼容JDK 1.4。
TaskExecutor
属于org.springframework.core.task
包下面,也是继承与java.util.concurrent.Executor
Java 1.7 引入了一种新的并发框架,主要用于实现“分而治之”的算法,特别是分治之后递归调用的函数,例如 quick sort 等。
ForkJoinPool 最适合的是计算密集型的任务,如果存在 I/O,线程间同步,sleep() 等会造成线程长时间阻塞的情况时,最好配合使用 ManagedBlocker。
具体请移步至
- http://blog.dyngr.com/blog/2016/09/15/java-forkjoinpool-internals/
- https://www.jianshu.com/p/32a15ef2f1bf
用于延时或者定期执行的异步任务/线程
提供线程池执行任务
ThreadPoolTaskExecutor
同样是提供线程池执行任务,但是可以使用xml或者JavaBean的形式进行配置,初始化。同样,ThreadPoolTaskExecutor
是使用ThreadPoolExecutor
。即也是ThreadPoolExecutor
的Spring包装。
ThreadPoolTaskScheduler
是ScheduledThreadPoolExecutor
一个spring形式的包装。Spring中任务的调度使用的就是这个类,比如@Scheduled
spring的TaskExecutor
的两个常用实现类均是基于Executor
实现类的包装,使其更加方便使用,更好的融入spring bean生态。
关于线程池的创建,拒绝策略等,网上资料很多了,将来有机会整理一下。
参考
http://blog.dyngr.com/blog/2016/09/15/java-forkjoinpool-internals/
https://www.jianshu.com/p/32a15ef2f1bf
https://stackoverflow.com/questions/39934115/difference-and-suggest-threadpooltaskexecutor-and-threadpoolexecutor