当前位置: 首页 > article >正文

Callable接口

1.用法

Callable是一个Interface。相当于把线程封装了一个“返回值”。方便程序员借助多线程的方式计算结果。

实例创建线程计算1+2+3+...+1000,不使用Callable版本

/**
 * Describe:不使用Callable计算1+2+3+...+1000的值
 * User:lenovo
 * Date:2023-03-30
 * Time:14:50
 */
public class TestDemo1 {
    private static int sum = 0;
    //private static Object object = new Object();

    public static void main(String[] args) throws InterruptedException {
        sum = 0;
        Thread t = new Thread(() -> {
            for (int i = 1; i <= 1000; i++) {
                sum += i;
            }
        });
        t.start();
        t.join();
        System.out.println(sum);
    }
}

此处我们可以发现,如果计算这个式子的值,我们就需要一个静态成员变量的配合,但是我们无法保证这个静态成员变量只是被我们这个代码使用,这就很容易出错。

创建线程计算1+2+3+...+1000,使用Callable版本

  • 创建一个匿名内部类,实现Callable接口类似于Runnable,用于描述线程具体要做的任务,Callable带有泛型参数,泛型参数表示返回值的类型;
  • 重写Callable的call方法,完成累加过程。直接通过返回值返回计算结果;
  • 把callable实例使用FutureTask包装(因为我们并不知道这个线程什么时间完成,我们使用FutureTask来管理它,存放放回的结果)一下;
  • 创建线程,线程的构造方法传入FutureTask.此时新线程就会执行FutureTask内部的Callable的call方法,完成计算。计算结果就放到FutureTask对象中。
  • 在主线程中调用futureTask.get()能够阻塞等待新线程计算完毕。并获取到FutureTask中的结果
public class TestDemo2 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Callable<Integer> callable = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int sum = 0;
                for (int i = 1; i <= 1000; i++) {
                    sum += i;
                }
                return sum;
            }
        };
        FutureTask<Integer> futureTask = new FutureTask<>(callable);
        Thread t = new Thread(futureTask);
        t.start();
        System.out.println(futureTask.get());
    }
}

可以看到,使用Callable和FutureTask之后,代码简化了好多。

理解Callable

Callable 和 Runnable相对,都是描述一个”任务“。Callable描述的是带有返回值的任务,

Runnable描述的是不带返回值的任务。

Callable通常需要搭配FutureTask来使用。FutureTask用来保存Callabel的返回结果。因为

Callable往往是在另一个线程中执行的,啥时候执行完并不确定。

FutureTask就可以负责这个等待结果出来的工作。

理解FutureTask

想象去学校食堂吃饭。点完餐后,后厨就开始做了,并给你一个号码。这个小票就是FutureTask。在饭做完的时候,我们就可以凭这个小票取餐了。

2.相关面试题

介绍一下Callable是什么?

Callable是一个interface.相当于把线程装了一个“返回值”。

Callable和Runnable是相对的,都是描述一个任务。Callable描述的是带有返回值的任务,Runnable描述的是不带返回值的任务。

Callable需要搭配FutureTask来使用。FutureTask用来保存Callable的返回值。因为我们并不知道Callable往往是在另一个线程中执行的,啥时候完成时不确定的。

FutureTask就是为了负责这个等待结果出来的工作。


http://www.kler.cn/a/4703.html

相关文章:

  • WPF 如何添加系统托盘
  • 小结:华为路由器常用的操作指令
  • Three.js 用户交互:构建沉浸式3D体验的关键
  • GitLab CI/CD使用runner实现自动化部署前端Vue2 后端.Net 7 Zr.Admin项目
  • 反转链表题目
  • Rust调用Windows API制作进程挂起工具
  • springboot整合redis实现秒杀功能
  • AI开发之——Leonardo—Finetuned Models及利用模型制图(5)
  • vue vben admin 使用, (个人感觉这项目封装的太深了!!!!)
  • 【故障诊断】用于轴承故障诊断的性能增强时变形态滤波方法及用于轴承断层特征提取的增强数学形态算子研究(Matlab代码实现)
  • JavaScript 基础 - 第3天
  • 刷题笔记【1】| 快速刷完67道剑指offer(Java版)
  • 四个常见的Linux面试问题
  • 2023年全国最新保安员精选真题及答案37
  • Qt 5基础 | 创建Hello World程序
  • day 14-文件操作
  • HTTP协议加强
  • 【C++】异常
  • Java中常见的密码学知识
  • 对于PM来说:拥有PMP证书,就拥有更多机会
  • 健身房训练计划—背部
  • 【学习笔记】CF1290
  • 【面试】如何定位线上问题?
  • 认证、认可、检验检测分不清?这篇必看
  • 是德N9030B频谱分析仪主要特性和功能
  • 高并发系统设计:缓存、降级、限流、(熔断)