Executor框架提供一种标准的方法将任务的提交过程和任务的执行过程解耦。
Executor基于生成者和消费者模式,提交任务相当于生产者,执行任务相当于消费者。
Executor
- 执行Runnable任务
ExecutorService
- 执行Runnable, Callable, FutureTask;
- 所有submit方法返回一个Future跟踪任务的进展。
- invokeAll方法可以执行一组任务
- ExecutorService的生命周期3种状态:运行,关闭和已终止
ThreadPoolExecutor
- 可以自定义线程池,实现ExecutorService接口
Executors
- 提供静态工厂方法创建线程池
- newFixedThreadPool(固定长度)
- newCachedThreadPool(不固定长度)
- newSingleThreadPool
- newScheduledThreadPool(固定长度)
Runnable
- run方法没有返回值,被Thread或Executor执行
Callable
- call方法有返回值并可抛出异常,被ExecutorService执行
Future
- 代表一个异步计算的结果, ExecutorService的所有submit方法返回一个Future。
表示任务的一个生命周期,提供相应的方法来判断是否已经完成或取消,以及获取任务执行的结果和取消任务。
get方法是阻塞方法,它的行为取决于任务的状态
如果任务完成,get方法立即返回或抛出一个Exception;
如果任务没有完成,get将阻塞并直到任务完成;
如果任务抛出异常,get将异常封装成ExecutionException并重新抛出;
如果任务被取消,get抛出CancallationException。
限时get方法
FutureTask
- 可取消的异步计算,实现了Runnable和Future接口, 可以直接提交给Executor执行。
- FutureTask包装了一个Callable或Runable对象。
- AbstractExecutorService的newTaskFor方法返回一个FutureTask对象。
ExecutorCompletionService
处理一组任务。使用Executor去执行任务,并将完成的结果(Future)放到一个BlockingQueue。
Executor执行任务有4个生命周期阶段:创建,提交,开始,完成。
示例
public class ExecutorDemo {
public int calc() {
int result = 0;
for(int i = 0; i < 10; i++) {
try {
Thread.sleep(TimeUnit.MILLISECONDS.toMillis(100));
} catch (InterruptedException e) {
e.printStackTrace();
}
result += i;
}
System.out.println(Thread.currentThread().getName());
return result;
}
public static void main(String[] args) {
ExecutorDemo demo = new ExecutorDemo();
FutureTask<Integer> futureTask = new FutureTask<Integer>(()->demo.calc());
ExecutorService exec = Executors.newFixedThreadPool(2);
exec.submit(futureTask);
exec.submit(()->System.out.println(Thread.currentThread().getName()));
try {
System.out.println(futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
//输出
pool-1-thread-2
pool-1-thread-1
45
main