Callable、Runnable、Future、RunnableFuture和FutureTask 深入理解

CallableRunnableFutureFutureTask 做为java 线程池运行的重要载体,有必要深入理解。
CallableRunnable 都是执行的任务的接口,区别在于Callable有返回值,而Runnable无返回值。
Future 表示异步任务返回结果的接口
RunnableFuture 继承了Runnable, Future,表示可以带有返回值的run接口
FutureTask是一个实现类,实现了RunnableFuture接口,既能接受Runnable类型的任务,也可以接受Callable类型的任务,这个类的作用主要是 有一个protected void done()方法用来扩展使用,作为一个回调方法。下面是一个例子:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;

public class FutureStudy {
    public static void main(String[] args) throws InterruptedException, ExecutionException {  
        ExecutorService executor = Executors.newCachedThreadPool(); 
        Future runFuture = executor.submit(new MyRunTask());
        Future callFuture = executor.submit(new MyCallTask());
        Future taskFuture = executor.submit(new MyFutureTask());
        System.out.println("任务全部提交成功,开始get 获取返回结果....... ");
        Thread.sleep(3000);

        System.out.println(runFuture.get());
        System.out.println(callFuture.get());
        System.out.println(taskFuture.get());
        executor.shutdown();  
    }  

    static class MyFutureTask extends FutureTask<String> {  

        public MyFutureTask(){
            this(new Callable(){

                @SuppressWarnings("unchecked")
                @Override
                public String call() throws Exception {
                    System.out.println(" FutureTask 线程执行完毕!~" );  
                    return (String) "FutureTask 返回值!~";
                }


            });
        }

        public MyFutureTask(Callable callable) {  
            super(callable);  
        }  

        @Override  
        protected void done() {  
            System.out.println("执行回调的done方法~"); 
        }     
    }  

    static class MyCallTask implements Callable<String> {  

        @Override  
        public String call() throws Exception {  
            System.out.println(" callable 线程执行完毕!~" );  
            return "callable返回值";  
        }  
    }

    static class MyRunTask implements Runnable {  

        @Override  
        public void run() {
            System.out.println(" runnable 线程执行完毕!~, 无返回值" );  
        }  
    }

上面的代码和简单,分别使用了Callable、Runnable和FutureTask作为任务提交给线程池来执行。
而只有Callable类型的任务才有返回值。
我们看看ExecutorService.submit方法的内部实现,

if (task == null) throw new NullPointerException();
        RunnableFuture ftask = newTaskFor(task);
        execute(ftask);
        return ftask;

protected  RunnableFuture newTaskFor(Runnable runnable, T value) {
        return new FutureTask(runnable, value);
    }

protected  RunnableFuture newTaskFor(Callable callable) {
        return new FutureTask(callable);
    }

由此可见,submit提交的任务都是转化为FutureTask来执行的。
下一篇文章来仔细分析FutureTask的源代码,请阅读 FutureTask源码分析

你可能感兴趣的:(concurrent)