Callable+Runnable+Future+RunnableFuture+FutureTask详解

1 Callable接口

Callable接口和Runnable接口功能相似。
执行Callable对象中的call方法可以抛出Checked Exception。

@FunctionalInterface
public interface Callable {
    V call() throws Exception;
}

2 Runnable接口

执行Runnable对象中的run方法不会抛出Checked Exception。

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

3 Future接口

一个Future对象代表一次异步计算的结果。

public interface Future {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

4 RunnableFuture接口

RunnableFuture接口是Runnable接口和Future接口的子接口。

public interface RunnableFuture extends Runnable, Future {
    // 这个run方法就是Runnable接口中的run方法
    void run();
}

5 FutureTask

FutureTask实现了RunnableFuture接口。

5.1 FutureTask中的字段

(1)state:任务运行状态。
(2)callable:callable中的call方法是需要执行的任务。
(3)outcome:call方法的返回值或call方法抛出的异常。
(4)runner:执行call方法的线程。
(5)waiters:一个栈的栈顶元素,这个栈用于保存处于阻塞状态的线程。如果一个线程调用FutureTask中的get方法,则该线程可能处于阻塞状态。

    private volatile int state;
    private Callable callable;
    private Object outcome;
    private volatile Thread runner;
    private volatile WaitNode waiters;

5.2 FutureTask.WaitNode内部类

(1)thread:一个处于阻塞状态的线程。
(2)next:栈中下一个元素。

    static final class WaitNode {
        volatile Thread thread;
        volatile WaitNode next;
        WaitNode() { thread = Thread.currentThread(); }
    }

5.3 FutureTask中的构造方法

    public FutureTask(Callable callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;
    }
    // 将runnable和result包装成callable
    public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;
    }
5.3.1 Executors中的callable方法
    public static  Callable callable(Runnable task, T result) {
        if (task == null)
            throw new NullPointerException();
        return new RunnableAdapter(task, result);
    }
    public static Callable callable(Runnable task) {
        if (task == null)
            throw new NullPointerException();
        return new RunnableAdapter(task, null);
    }
    public static Callable callable(final PrivilegedAction action) {
        if (action == null)
            throw new NullPointerException();
        return new Callable() {
            public Object call() { return action.run(); }};
    }
    public static Callable callable(final PrivilegedExceptionAction action) {
        if (action == null)
            throw new NullPointerException();
        return new Callable() {
            public Object call() throws Exception { return action.run(); }};
    }
 
 
5.3.1.1 Executors.RunnableAdapter内部类

Executors.RunnableAdapter实现了Callable接口。

    static final class RunnableAdapter implements Callable {
        final Runnable task;
        final T result;
        RunnableAdapter(Runnable task, T result) {
            this.task = task;
            this.result = result;
        }
        public T call() {
            task.run();
            return result;
        }
    }

5.4 FutureTask中的任务运行状态

(1)NEW:callable中的call方法尚未执行或正在执行。
(2)COMPLETING:callable中的call方法执行完毕(正常结束或抛出异常),正在保存outcome(如果正常结束,outcome等于call方法的返回值;如果抛出异常,outcome等于call方法抛出的异常)。
(3)NORMAL:callable中的call方法正常结束,outcome保存完毕。
(4)EXCEPTIONAL:callable中的call方法抛出异常,outcome保存完毕。
(5)CANCELLED:任务运行状态等于NEW时,调用cancel(false)方法,任务运行状态转换为CANCELLED。
(6)INTERRUPTING:任务运行状态等于NEW时,调用cancel(true)方法,任务运行状态转换为INTERRUPTING。
(7)INTERRUPTED:任务运行状态转换为INTERRUPTING之后,中断runner,任务运行状态转换为INTERRUPTED。

    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;

5.5 FutureTask中的任务运行状态的转换

(1)NEW -> COMPLETING -> NORMAL:任务正常结束。
(2)NEW -> COMPLETING -> EXCEPTIONAL:任务抛出异常。
(3)NEW -> CANCELLED:任务被取消。
(4)NEW -> INTERRUPTING -> INTERRUPTED:任务被中断。

5.6 FutureTask中的run方法

    public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable c = callable;
            if (c != null && state == NEW) {
                V result;
                // ran代表callable中的call方法是否正常结束
                boolean ran;
                try {
                    // 执行callable中的call方法
                    result = c.call();
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    // call方法抛出异常
                    // 保存outcome;唤醒栈中所有线程,调用done方法,将callable设为null
                    // done方法是空方法,子类中可以重写该方法
                    setException(ex);
                }
                if (ran)
                    // call方法正常结束
                    // 保存outcome;唤醒栈中所有线程,调用done方法,将callable设为null
                    // done方法是空方法,子类中可以重写该方法
                    set(result);
            }
        } finally {
            runner = null;
            int s = state;
            // 如果任务运行状态等于INTERRUPTING或INTERRUPTED
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }
5.6.1 FutureTask中的handlePossibleCancellationInterrupt方法
    // 传入的s可能是INTERRUPTING、INTERRUPTED
    private void handlePossibleCancellationInterrupt(int s) {
        if (s == INTERRUPTING)
            while (state == INTERRUPTING)
                Thread.yield();
    }

5.7 FutureTask中的runAndReset方法

    protected boolean runAndReset() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return false;
        // ran代表callable中的call方法是否正常结束
        boolean ran = false;
        int s = state;
        try {
            Callable c = callable;
            if (c != null && s == NEW) {
                try {
                    // 执行callable中的call方法
                    c.call();
                    // call方法正常结束
                    // 不保存outcome
                    ran = true;
                } catch (Throwable ex) {
                    // call方法抛出异常
                    // 保存outcome;唤醒栈中所有线程,调用done方法,将callable设为null
                    // done方法是空方法,子类中可以重写该方法
                    setException(ex);
                }
            }
        } finally {
            runner = null;
            s = state;
            // 如果任务运行状态等于INTERRUPTING或INTERRUPTED
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
        return ran && s == NEW;
    }

5.8 FutureTask中的cancel方法

cancel方法执行时:
(1)如果任务运行状态不等于NEW,返回false。
(2)如果任务运行状态等于NEW并且call方法尚未执行,则call方法永远不会执行。
(3)如果任务运行状态等于NEW并且call方法正在执行但尚未执行完毕,传入的mayInterruptIfRunning决定是否中断runner。
cancel方法执行完毕:
(1)调用isDone方法会一直返回true。
(2)如果cancel方法返回true,调用isCancelled方法会一直返回true。

    public boolean cancel(boolean mayInterruptIfRunning) {
        if (!(state == NEW &&
              UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                  mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
            return false;
        // 运行到这里,说明当前线程将任务运行状态从NEW转换为CANCELLED或INTERRUPTING
        try {
            if (mayInterruptIfRunning) {
                try {
                    Thread t = runner;
                    if (t != null)
                        t.interrupt();
                } finally {
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                }
            }
        } finally {
            // 唤醒栈中所有线程,调用done方法,将callable设为null
            // done方法是空方法,子类中可以重写该方法
            finishCompletion();
        }
        return true;
    }

5.9 FutureTask中的isCancelled方法

    public boolean isCancelled() {
        return state >= CANCELLED;
    }

5.10 FutureTask中的isDone方法

    public boolean isDone() {
        return state != NEW;
    }

5.11 FutureTask中的get方法

    public V get() throws InterruptedException, ExecutionException {
        int s = state;
        // 如果任务运行状态等于NEW或COMPLETING
        if (s <= COMPLETING)
            s = awaitDone(false, 0L);
        return report(s);
    }
    public V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException {
        if (unit == null)
            throw new NullPointerException();
        int s = state;
        // 如果(任务运行状态等于NEW或COMPLETING)并且(经过给定时间之后任务运行状态依然等于NEW或COMPLETING)
        if (s <= COMPLETING &&
            (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
            throw new TimeoutException();
        return report(s);
    }
5.11.1 FutureTask中的report方法
    // 传入的s可能是NORMAL、EXCEPTIONAL、CANCELLED、INTERRUPTING、INTERRUPTED
    private V report(int s) throws ExecutionException {
        Object x = outcome;
        // 如果任务运行状态等于NORMAL
        if (s == NORMAL)
            return (V)x;
        // 如果任务运行状态等于CANCELLED或INTERRUPTING或INTERRUPTED
        if (s >= CANCELLED)
            throw new CancellationException();
        // 如果任务运行状态等于EXCEPTIONAL
        throw new ExecutionException((Throwable)x);
    }

你可能感兴趣的:(Callable+Runnable+Future+RunnableFuture+FutureTask详解)