聊聊高并发(四十一)解析java.util.concurrent各个组件(十七)

聊聊高并发(三十九)解析java.util.concurrent各个组件(十五) 理解ExecutorService接口的设计这篇说了ExecutorService接口扩展了Executor接口,在执行任务的基础上,提供了执行框架生命周期的管理,任务的异步执行,批量任务的执行的能力。AbstractExecutorService抽象类实现了ExecutorService接口,提供了任务异步执行和批量执行的默认实现。这篇说说任务的异步执行和状态控制

说明一点,使用Executor框架执行任务的方式基本都是异步执行的,交给线程池的线程来执行。ExecutorService在任务异步执行的基础上,通过Future接口来对异步执行的任务进行状态控制。

submit方法可以返回Future对象来对异步执行任务进行控制。submit方法有三种调用方式,传递Runnable, Runnable和result,Callable。

public Future<?> submit(Runnable task) {if (task == null) throw new NullPointerException();RunnableFuture<Void> ftask = newTaskFor(task, null);execute(ftask);return ftask;}public <T> Future<T> submit(Runnable task, T result) {if (task == null) throw new NullPointerException();RunnableFuture<T> ftask = newTaskFor(task, result);execute(ftask);return ftask;}public <T> Future<T> submit(Callable<T> task) {if (task == null) throw new NullPointerException();RunnableFuture<T> ftask = newTaskFor(task);execute(ftask);return ftask;}

从submit的实现可以看到,都是使用了newTaskFor方法进行了接口的适配,返回一个RunnableFuture类型

protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {return new FutureTask<T>(runnable, value);}protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {return new FutureTask<T>(callable);}来看一下对异步执行的任务进行控制的Future接口相关的类

1. Ruuable表示可被Thread执行的任务,它的run方法没有返回值,并且没有显式的异常

2. Callable表示可以调用的任务,它的call方法可以有返回值,可以抛出显式的异常

3. Future接口是对异步执行的任务的控制,包括取消任务,判断任务状态,获取任务结果等操作

4. RunnableFuture是对Runnable接口和Future接口的适配,表示可以被控制状态的Runnable

5. RunnableAdapter是对Runnable和Callalbe的适配,实现了Callable接口,并聚合了Runnable对象

6. FutureTask实现了RunnableFuture接口,通过RunnableAdapter对传入的Callable和Runnable参数进行统一处理

public interface Runnable {public abstract void run();}public interface Callable<V> {    V call() throws Exception;}static final class RunnableAdapter<T> implements Callable<T> {        final Runnable task;        final T result;        RunnableAdapter(Runnable task, T result) {            this.task = task;            this.result = result;        }        public T call() {            task.run();            return result;        }    }public interface Future<V> {    boolean cancel(boolean mayInterruptIfRunning);       boolean isCancelled();       boolean isDone();    V get() throws InterruptedException, ExecutionException;    V get(long timeout, TimeUnit unit)        throws InterruptedException, ExecutionException, TimeoutException;}public interface RunnableFuture<V> extends Runnable, Future<V> {    void run();}在ExecutorService的submit方法中可以看到最终被执行的任务是包装成了RunnableFuture类型,它既是Runnable可以被Executor执行,又是Future,可以控制异步执行的Runnable的状态。

重点来看一下RunnableFuture的实现类FutureTask,异步执行的任务的状态控制都是在这个类中实现的。

FutureTask的主要属性

1. private volatile int state; volatile类型的state,保存当前任务的状态,状态有下面几种

private static final int NEW = 0; private static final int COMPLETING = 1; private static final int NORMAL = 2; private static final int EXCEPTIONAL = 3; private static final int CANCELLED = 4; private static final int INTERRUPTING = 5; private static final int INTERRUPTED = 6;

2. private Callable<V> callable; 可以获得计算结果的callable对象,封装了传入的任务

3. private Object outcome; 任务执行的结果,可以是正常计算得到的结果,也可以是要返回的异常

4. private volatile Thread runner; 执行任务的线程

5. private volatile WaitNode waiters; 等待的线程链表

也不要说曾经失去,失去的不是永远失去,得到的不是永远拥有,

聊聊高并发(四十一)解析java.util.concurrent各个组件(十七)

相关文章:

你感兴趣的文章:

标签云: