JAVA多线程系列之一:Executor框架
在Java中,使用线程来异步执行任务。Java线程的创建与销毁需要一定的开销,如果我们为每个任务创建一个新线程来执行,这些线程的创建于销毁将消耗大量的计算资源。同时,为每一个任务创建一个新线程来执行,这种策略可能会使处于高负荷状态的应用最终崩溃。
Java的线程既是工作单元,也是执行机制。从JDK 5开始,把工作单元和执行机制分离开来。工作单元包括Runnable和Callable,而执行机制由Executor框架提供。
下面是本篇要介绍的内容:
Executor框架简介
1 Executor框架的结构
1.1 Executor框架的组成
Executor框架主要由三大部分组成:
1)任务。包括被执行任务需要实现的接口:Runnable接口或Callable接口。
2)任务的执行。包括任务执行机制的核心接口Executor,以及继承与Executor的ExecutorService接口。Executor框架中有两个关键类实现了ExecutorService接口(ThreadPoolExecutor和ScheduledThreadPoolExecutor)
3)异步计算的结果。包括接口Future和实现Future接口的FutureTask类。
1.2 Executor框架类和接口
Executor框架包含的主要类和接口如下图所示。
Executor框架的常用类和接口结构图
线程对象及线程执行返回的对象
(1)Executor是一个接口,它是Executor框架的基础,它将任务的提交与任务的执行分离开来,包括线程使用,调度的细节。里面提供了一个execute方法,该方法接收一个Runnable参数,如下:
public interface Executor{
/**
*
* @param command 执行提交任务
* @throws RejectedExecutionException 如果该任务无法被执行
* @throws NullPointerException 如果commad 为 null
*/
void execute(Runnable command);
}
(2)ExecutorService是一个接口,该对象提供方法来管理终止和追踪(Future)多个程序。
public interface ExecutorService extends Executor{
//启动有序关闭,其中先前提交的任务将被执行,但不会再接受如何新任务。
void shutdown();
//试图关闭所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表
List<Runnable> shutdownNow();
//返回该执行器是否被关闭
boolean isShutdown();
//返回true如果所有的任务完成以下关闭。注意{isTerminate()}永远不会为true,除非先调用{shutdown()}或者{shutdownNow()}
boolean isTerminate();
//阻止所有任务在关闭请求之后执行,或者发生超时,或者当前线程被中断
boolean awaitTermination(long timeout,TimeUnit unit) throws InterruptedException;
//提交value-returning任务以供执行并返回一个Future呈现有待结果的任务。
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Callable<T> task,T result);
Future<?> submit(Runnable task);
//执行所有任务,当所有任务完成后返回持有Future及其状态和结果集合。
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
throws InterruptedException;
<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
long timeout, TimeUnit unit)
throws InterruptedException;
//执行给予的任务,返回成功完成的其中一个任务
<T> T invokeAny(Collection<? extends Callable<T>> tasks)
throws InterruptedException,ExecutionException;
<T> T invokeAny(Collection<? extends Callable<T>> tasks,
long timeout,TimeUnit unit)
throws InterruptedException,ExecutionException,TimeoutException;
}
(3)ThreadPoolExecutor是线程池的核心类,用来执行被提交的任务。应为Executors工厂大部分方法都是返回ThreadPoolExecutor对象。先来看看它的构造函数吧。
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {...}
参数 | 类型 | 含义 |
---|---|---|
corePoolSize | int | 核心线程数 |
maximumPoolSize | int | 最大线程数 |
keepAliveTime | long | 存活时间 |
unit | TimeUnit | 时间单位 |
workQueue | BlockingQueue | 存放线程的阻塞队列 |
threadFactory | ThreadFactory | 创建线程的工厂 |
handler | RejectedExecutionHandler | 多余的的线程处理器(拒绝策略) |
(4)ScheduledThreadPoolExecutor是一个实现类,可以在给定的延迟后运行命令,或者定期执行命令。ScheduledThreadPoolExecutor比Timer更灵活,功能更强大。这个类和ThreadPoolExecutor再详细讲解。
(5)Future接口和实现Future接口的FutureTask类,代表异步计算的结果。这个也在后面详解。
(6)Runnable接口和Callable接口的实现类,都可以被ThreadPoolExecutor和ScheduledThreadPoolExecutor执行。
Executor框架使用流程图
2 Executor框架的成员
Executor框架的主要成员:ThreadPoolExecutor、ScheduledThreadPoolExecutor、Future接口、Runnable接口、Callable接口和Executors.
2.1 ThreadPoolExecutor
ThreadPoolExecutor 通常使用工厂类Executors来创建。Executors可以创建3种类型的ThreadPoolExecutor:SingleThreadExecutor、FixedThreadPool和CachedThreadPool。
2.1.1 FixedThreadPool。
下面由Executors提供的,创建使用固定线程数的FixedThreadPool的api。
//创建一个线程池,该线程池重用在共享的无界队列中运行的固定数量的线程。
//有新的任务被提交加入当nThreads个线程都在运行时,新的线程会加入等待队列中,直到它可获取。
public static ExecutorService newFixedThreadPool(int nThreads){}
public static ExecutorService newfixedThreadPool(int nThreads,ThreadFactory threadFactory) {
FixedThreadPool适用于为了满足资源管理的需求,而需要限制当前线程数量的应用场景。
2.1.2 SingleThreadExecutor
下面由Executors提供的,创建使用单个线程的SingleThreadExecutor的api。
public static ScheduledExecutorService newSingleThreadScheduledExecutor(){}
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory){}
2.1.3 CachedThreadPool
下面由Executors提供的,创建一个会根据需要创建新线程的CachedThreadPool的api。
public static ExecutorService newCachedThreadPool(){}
public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory){}
CachedThreadPool是大小无界的线程池,适用于执行很多的短期异步小任务,或者是负载较轻的服务器。
2.2 ScheduledThreadPool
ScheduledThreadPool通常使用工厂类Executors来创建。Executors可以创建两种类型的ScheduledThreadPool,如下。
ScheduledThreadPoolExecutor。包含若干个线程的ScheduledThreadPoolExecutor。
SingleThreadScheduledExecutor。只包含一个线程的ScheduledThreadPoolExecutor。
2.2.1 ScheduledThreadPoolExecutor
下面由Executors提供的,创建固定个数的ScheduledThreadPoolExecutor的api。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize){}
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize,
ThreadFactory threadFactory)
ScheduledThreadPoolExecutor适用于需要多个后台线程执行周期任务,同时为了满足资源管理的需求而需要限制后台线程的数量的应用场景。
2.2.2 SingleThreadScheduledExecutor
下面由Executors提供的,创建单个线程的SingleThreadScheduledExecutor 的api。
public static ScheduledExecutorService newSingleThreadScheduledExecutor(){}
public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory){}
SingleThreadScheduledExecutor适用于需要单个后台线程执行周期任务,同时需要保证顺序地执行各个任务的应用场景。
Future接口和Callable接口将在下一篇文章详细介绍!
本人第一次写博客,可能存在很多不足的地方,希望大家能多提意见,已供我改正。同时也欢迎大家提问题,能回复的我一定会回复,一起共同进步!