《java.util.concurrent 包源码阅读》09 线程池系列之介绍篇
concurrent包中Executor接口的主要类的关系图如下:
Executor接口非常单一,就是执行一个Runnable的命令。
public interface Executor { void execute(Runnable command); }
ExecutorService接口扩展了Executor接口,增加状态控制,执行多个任务返回Future。
关于状态控制的方法:
// 发出关闭信号,不会等到现有任务执行完成再返回,但是现有任务还是会继续执行, // 可以调用awaitTermination等待所有任务执行。不再接受新的任务。 void shutdown(); // 立刻关闭,尝试取消正在执行的任务(不保证会取消成功),返回未被执行的任务 List<Runnable> shutdownNow(); // 是否发出关闭信号 boolean isShutdown(); // 是否所有任务都执行完毕在shutdown之后,也就是如果不调用shutdownNow或者 // shutdown是不可能返回true boolean isTerminated(); // 进行等待直到所有任务完成或者超时 boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
提交单个任务,立刻返回一个Future存储任务执行的实时状态
<T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result); Future<?> submit(Runnable task);
执行多个任务的方法,有两种方式,一种等到所有任务执行完成才返回:
<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;
通过上面的代码可以看出ExecutorService可以执行两种类型的任务:Runnable和Callable,而Callable用的更加多。两者区别很简单,前者不会返回执行结果而后者会返回一个执行结果:
public interface Callable<V> { V call() throws Exception; }
接着说说Future,也就是执行任务的返回类型。Future可以看成是一张发票。比如你送件衣服到洗衣店清洗,他们会开张发票给你,你拿着发票可以去拿回你洗好的衣服或者去洗衣店问衣服是否洗好了等等。
public interface Future<V> { //取消任务,参数mayInterruptIfRunning为true时,如果要取消的任务正在执行, //会把执行这个任务的线程设为中断,为false时,正在执行的任务会被允许执行完成 boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); //获取执行结果,如果任务执行中,会等到任务完成再返回 V get() throws InterruptedException, ExecutionException; V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException; }
最后看看ScheduledExecutorService接口,该接口是ExecutorService的子接口,增加了定时执行任务的功能:
public interface ScheduledExecutorService extends ExecutorService { public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit); public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit); // 等待一定时间然后开始执行一个任务,每隔period参数设置的时间 // 重复一次,(多线程执行) public ScheduledFuture<?> scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit); // 等待一定时间然后开始执行一个任务,完成后,等待delay参数设置的时间 // 然后在执行一次任务。(单线程执行) public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit); }
这篇文章主要就讲到了concurrent包关于线程池的相关接口,接下来会讲AbstractExecutorService,ThreadPoolExecutor和ScheduledThreadPoolExecutor。