概述
Java1.5后引入的Executor框架。虽然Executor是一个简单的接口,确为灵活而且强大的异步任务执行框架提供了基础。Executor的优点:
- 任务的提交和执行解耦,并用Runnable表示任务。
- Executor的实现提供了对线程生命周期的支持。
- Executor的实现能支持不同类型的任务的提交和不同的执行策略。
通过将任务的提交和执行解耦,很容易就可以指定任务和修改执行策略。而在执行策略中定义了指定了任务的“what,where,when,how”等。
- 在什么(what)线程中执行?
- 任务按照什么(what)顺序执行(FIFO,LIFO,优先级)?
- 有多少个(How many) 任务能并发执行?
- 在队列中又多少个(How many)任务在等待任务?
- 如果系统由于过载而需要拒绝一个任务,那么应该选择哪一个(which)任务执行?另外,如何(How)通知应用程序有任务被拒绝了?
- 在执行一个任务之前或者之后,应该进行哪些(what)动作?
Executor框架
public interface Executor {
void execute(Runnable command);
}
Executor仅仅提供标准的接口。
常见子类
ExecutorService
ExecutorService
接口在原有的Executor
的基础上,添加了生命周期的管理和submit
方法返回Future
对象。
AbstractExecutorService
AbstractExecutorService提供了ExecutorService
接口方法的一些默认实现。此类实现了submit
, invokeAny
and invokeAll
方法,submit
方法内部实现中使用RunnableFuture
作为返回值,而默认的实现是 FutureTask
类。
ThreadPoolExecutor
ThreadPoolExecutor
线程池,使用线程池中的一个线程来执行提交的任务。
线程池解决了两个问题:
- 减少了per-task的调用的开销,当执行大量的异步的Task的时候提高了性能。
- 限制和管理资源的功能,包括工作线程以及任务的资源消耗。比如一个数据库最多支持5个连接,那我们可以使用线程池来限制线程的数量,从而满足需求。
ScheduledExecutorService
ScheduledExecutorService
仅仅增加了schedule
相关的方法来延迟执行任务。
ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor
继承自ThreadPoolExecutor
,但可以延迟执行任务。当需要多个工作线程时,ScheduledThreadPoolExecutor
比Timer
更适合或者是要求必须继承ThreadPoolExecutor提供另外的灵活性时才需要。
Future接口
Future
接口表示的是异步的运行结果。
RunnableFuture
接口继承自Runnable
和Future
接口,这样RunnableFuture
也是一个Commond,便于使用。
FutureTask
接口实现了RunnableFuture
接口,真正的操作依赖Callable
。
Callable
接口标识带返回值的任务,与Runnable最大的不同是有返回值。
参考资料
- 《Java并发编程实战》
- 《Java并发编程-设计原则与模式》