Runnable,Callable,Future,FutureTask的区别

Runnable,Callable,Future,FutureTask的区别:
参考:https://baijiahao.baidu.com/s?id=1631326488605078999&wfr=spider&for=pc
一般创建线程的方法:继承Thread,实现Runnable
这两种都没有返回值,一般需要用到Handler去发送结果然后处理;
在这两种传统方法中,推荐Runnable,因为Thread只能继承,Java只有单继承,而Runnable是通过接口;
并且在线程池中,Runnable可以直接传入其中使用;如

private ExecutorService executorService = Executors.newFixedThreadPool(5);
executorService.execute(new Runnable() {
            @Override
            public void run() {
                //.....
            }
        });

在java1.5之后有了Callable和Future,这两种可以提供线程返回的结果;

1.Runnable:

Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //...
            }
        });
thread.start();


附带:thread的start和run有什么区别?
start是开启新线程,这时线程处于就绪状态,一旦得到cpu时间片,边开始运行;
run:只是类的一个普通方法而已,如果直接调用run,程序中依然只有主线程;

2.Callable
和Runnable的区别是有返回结果,且可以抛出异常;一般是配合线程池调用;

Callable callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "result";
            }
        };

        ExecutorService executorService = Executors.newFixedThreadPool(5);
        Future future = executorService.submit(callable);
        try {
            System.out.println(future.get());
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

3.Future
Future也是一个接口,它可以对具体的Runnable或者Callable任务进行取消,获取运行结果;
如果是Runnable的话获取的结果为null,get会阻塞当前调用get的线程,直到返回结果或者超时才会唤醒当前线程;

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.FutureTask
相比与Future的好处是Future是一个接口,不能直接new;
而FutureTask是一个class,实现了RunnableFuture接口;
RunnableFuture 又实现了Runnable和Future两个接口;
因此FutureTask既可以作为Runnable被线程执行,又有着Future的特性(获取结果/抛异常);

 public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
    }

 public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);
        this.state = NEW;       // ensure visibility of callable
    }

使用

  FutureTask futureTask = new FutureTask(callable);
    //由于futureTask自带返回结果,所以可以不用submit方法
        executorService.execute(futureTask); 
        try {
            System.out.println(futureTask.get());
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


5.submit方法
疑问:为什么使用submit方法而不用execute方法?
答:需要返回结果就要用submit;
submit方法实现

//传入的是Runnable,将Runnable转化为FutureTask实例
public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }

//传入的是Callable,将Runnable转化为FutureTask实例
public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }

//FutureTask是RunnableFuture接口的实现类
protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }

所以submit之所以可以返回结果,其实就是使用了FutureTask
submit就是将传入的Runnable或者Callable转化为RunnableFuture,然后调用execute
因此如果一开始就是FutureTask,则可以直接使用execute.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值