JAVA多线程进阶篇 10、JUC之Callable Future FutureTask

了解线程池之前需要对线程定义的方法进一步补充,可以参见《JAVA多线程基础篇 2、如何创建线程》

1. Callable

在JDK5之后,增加了Callable接口,实现该接口的类,可以类似Runnable方法,在多线程环境中运行,并且返回运行结果。

public class CallableA implements Callable<String>{

    @Override
    public String call() throws Exception {
        //模拟耗时计算
        Thread.sleep(1000);
        return "您好 ! 蛋糕做好了";
    }
}

2. Future与线程池配合运行

调用Callable对象,需要配合Future和线程池。
线程池提交Callable任务后,会返回Future对象.此时Future对象只是一个占位符,就好像去订蛋糕,蛋糕店会给你一张提货小票。
当调用future.get()方法时,才会阻塞直到获取结果。

    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newCachedThreadPool();
        Future<String> future = executorService.submit(new CallableA());
        System.out.println(future.get());
        executorService.shutdown();
    }

运行结果:

您好 ! 蛋糕做好了

3. FutureTask

FutureTask非常灵活。它同时实现了Runnable接口和Callable接口,,还实现了Future接口。所以FutureTask既能当做一个Runnable直接被Thread执行,也能作为Future用来得到Callable的计算结果。

3.1 FutureTask作为线程单独运行

public class FutureTaskTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        Callable<String> makecake = new Callable<String>(){
            @Override
            public String call() throws Exception {
                return "蛋糕做好了";
            }
        };

        FutureTask<String> task = new FutureTask(makecake);

        new Thread(task).start();

        System.out.println(task.get());

    }
}

运行结果:

您好 ! 蛋糕做好了

3.2 FutureTask与线程池配合运行

也可以将FutureTask提交到线程池运行,然后从FutureTask里取出Future结果。
因为FutureTask即实现了Runnable接口和Callable,还实现了Future接口。


public class FutureTaskTest2 {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        Callable<String> makecake = new Callable<String>(){
            @Override
            public String call() throws Exception {
                return "蛋糕做好了";
            }
        };

        FutureTask<String> task = new FutureTask(makecake);

        ExecutorService executorService = Executors.newCachedThreadPool();

        executorService.submit(task);

        System.out.println(task.get());
    }
}

运行结果:

您好 ! 蛋糕做好了

总结

除了Runnable接口外,Callable结合线程池、以及FutureTask类都可以提交线程任务。

多线程系列在github上有一个开源项目,主要是本系列博客的实验代码。

https://github.com/forestnlp/concurrentlab

如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。

您的支持是对我最大的鼓励。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟空学编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值