美文网首页
Callable+Runnable+Future+Runnabl

Callable+Runnable+Future+Runnabl

作者: 永远的太阳0123 | 来源:发表于2018-12-18 10:20 被阅读0次

    1 Callable接口

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

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

    2 Runnable接口

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

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

    3 Future接口

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

    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;
    }
    

    4 RunnableFuture接口

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

    public interface RunnableFuture<V> extends Runnable, Future<V> {
        // 这个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<V> 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<V> 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 <T> Callable<T> callable(Runnable task, T result) {
            if (task == null)
                throw new NullPointerException();
            return new RunnableAdapter<T>(task, result);
        }
        public static Callable<Object> callable(Runnable task) {
            if (task == null)
                throw new NullPointerException();
            return new RunnableAdapter<Object>(task, null);
        }
        public static Callable<Object> callable(final PrivilegedAction<?> action) {
            if (action == null)
                throw new NullPointerException();
            return new Callable<Object>() {
                public Object call() { return action.run(); }};
        }
        public static Callable<Object> callable(final PrivilegedExceptionAction<?> action) {
            if (action == null)
                throw new NullPointerException();
            return new Callable<Object>() {
                public Object call() throws Exception { return action.run(); }};
        }
    
    5.3.1.1 Executors.RunnableAdapter内部类

    Executors.RunnableAdapter实现了Callable接口。

        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;
            }
        }
    

    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<V> 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<V> 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+Runnabl

          本文链接:https://www.haomeiwen.com/subject/rrskkqtx.html