专栏首页java开发的那点事简单理解Callable接口
原创

简单理解Callable接口

Callable接口:

  Callable,新启线程的一种方式,返回结果并且可能抛出异常的任务,在前面的新启线程的文章中用过,但是没有具体讲解

  优点:

    可以获取线程的执行结果,也称为返回值

    通过与Future的结合,可以实现利用Future来跟踪异步计算的结果

Runnable和Callable的区别:

  Callable规定的方法是call(),Runnable规定的接口是run();

  Callable的任务执行后可返回值,而Runnable的任务是不能有返回值的;

  call方法可以抛出异常,run方法不可以

  运行Callable任务可以拿到一个Future对象,表示异步计算的结果,它提供了检查是否计算完成的方法,以等待计算的完成,并检索计算的结果,通过Future对象可以了解任务执行情况,可以取消任务的执行,还可以获取执行结果

Future接口:

  Future是一个接口,代表了一个异步计算的结果,接口中的方法用来检查计算是否完成,等待完成和得到计算结果;

  当计算完成后,只能通过get()方法得到结果,get()方法会阻塞,一直到线程的计算结果完成并返回;

  如果想取消,那么调用cancel()方法,其他方法用于确定任务是正常完成还是取消了;

  一旦计算完成了,那么这个计算就不能被取消

FutureTask类:

  FutureTask类实现了RunnableFuture接口,而RunnableFuture接口是继承了Runnable和Future接口,所以说FutureTask是一个提供异步计算结果的任务;

  FutureTask可以用来包装Callable或者Runnable接口的实现对象,因为FutureTask实现了Runnable接口,所以FutureTask也可以提交给线程池

Callable,Future,FutureTask三者之间的关系:

Callable,Future,FutureTask三者之间的关系:

Callable的两种执行方式:

1:借助FutureTask,包装Callable接口的实现类,然后传递给Thread线程执行

package org.dance.day2.future;

import org.dance.tools.SleepTools;

import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * Callable的两种执行方式
 * @author ZYGisComputer
 */
public class UseCallable {

    /**
     * 实现Callable接口的线程
     */
    private static class UseCall implements Callable<Integer>{

        private int sum;

        @Override
        public Integer call() throws Exception {
            System.out.println("callable子线程开始执行任务计算");
            Thread.sleep(2000);
            for (int i = 0; i < 5000; i++) {
                sum += i;
            }
            System.out.println("子线程任务计算完成,返回值:"+sum);
            return sum;
        }
    }

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

        UseCall useCall = new UseCall();

        // 使用FutureTask包装
        FutureTask<Integer> futureTask = new FutureTask<>(useCall);

        // 包装为Thread
        Thread thread = new Thread(futureTask);

        thread.start();

        // 开始主线程的任务
        Random random = new Random();

        SleepTools.second(1);

        if(random.nextBoolean()){
            System.out.println("获取Callable result:"+futureTask.get());
        }else{
            System.out.println("中断计算");
            // 中断计算,取消线程的执行
            futureTask.cancel(true);
        }
    }

}

2:借助线程池来执行

UseCall useCall = new UseCall();
 // 创建一个线程池
ExecutorService executorService = Executors.newCachedThreadPool();
Future<Integer> future = executorService.submit(useCall);

线程池这个只粘贴关键代码,线程池的知识就不在这多说了,之后会具体讲解

返回的Future接口的使用和FutureTask是一样的

这个接口实现的线程,是有返回值的

可以说一下我之前用到的场景

是这样的,我之前用到的一般是用于云上,或者存储服务器下载电子文件,就是本身我一个接口就是需要查询数据库并,进行结果的大量计算和结果转换的,同时还要上云上下载比较大的电子文件,所以我采用Callable配合线程池来完成云上文件的下载;

作者:彼岸舞

时间:2020\10\04

内容关于:并发编程

本文来源于网络,只做技术分享,一概不负任何责任

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 线程的基础概念与理论

    虽说线程的数量是有限的,但是我们平时在用的过程中并没有,发现线程受限制,这就涉及到CPU的时间片轮转机制了,也称为RR调度

    彼岸舞
  • Spring security OAuth2.0认证授权学习第一天(基础概念-认证授权会话)

    这段时间没有学习,可能是因为最近工作比较忙,每天回来都晚上11点多了,但是还是要学习的,进过和我的领导确认,在当前公司的技术架构方面,将持续使用Spring s...

    彼岸舞
  • Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definiti

    昨天还好好的项目,今天突然提示这个错误,看提示好像是EasyPoi的一个Bean的注册和Spring中的一个Bean的注册名称碰撞了

    彼岸舞
  • 不会用Java Future,我怀疑你泡茶没我快, 又是超长图文!!

    现陆续将Demo代码和技术文章整理在一起 Github实践精选 ,方便大家阅读查看,本文同样收录在此,觉得不错,还请Star

    用户4172423
  • Java多线程面试准备:聊聊Executor框架

    在HotSpot VM的线程模型中,Java线程被一对一映射为本地操作系统线程。Java线程启动时会创建一个本地操作系统线程;当Java线程终止时,这个操作系统...

    好好学java
  • Future && FutureTask

    线程的创建方式中有两种,一种是实现Runnable接口,另一种是继承Thread,但是这两种方式都有个缺点,那就是在任务执行完成之后无法获取返回结果,于是就有了...

    大学里的混子
  • Java的synchronized

    synchronized主要的作用: 保证在同一时刻,只有一个线程可以执行某个方法或某个代码块(原子性),同时synchronized可以保证一个线程的变化可见...

    用户3467126
  • 线程与进程的区别

    莫问今朝
  • 互联网高级面试题目

    覆盖(Override)是指子类对父类方法的一种重写,只能比父类抛出更少的异常,访问权限不能比父类的小。

    故久
  • 线程和进程

    进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.

    邹志全

扫码关注云+社区

领取腾讯云代金券