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

来源:互联网 发布:买卖宝软件下载 编辑:程序博客网 时间:2024/04/29 19:36

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<String> 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<String>(){                @SuppressWarnings("unchecked")                @Override                public String call() throws Exception {                    System.out.println(" FutureTask 线程执行完毕!~" );                      return (String) "FutureTask 返回值!~";                }            });        }        public MyFutureTask(Callable<String> 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<T> ftask = newTaskFor(task);        execute(ftask);        return ftask;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);    }

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

    0 0
    原创粉丝点击