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<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源码分析

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值