并发编程修十二:Callable、Future和FutureTask

MPU6050 加速度计和陀螺仪传感器与 Arduino 的接口 虽然该模型并不能准确代表现实世界中加速度计传感器的构建方式,但它通常有助于理解为什么加速度计的输出信号通常以 ±g 为单位指定,或者为什么加速度计在静止时在 z 轴上的读数为 1g,或者在不同方向上您可以期望得到什么样的加速度计读数。该模块的核心是低功耗、低成本的 6 轴运动跟踪芯片 MPU6050,它将 3 轴陀螺仪、3 轴加速度计和数字运动处理器 (DMP) 集成到一个 4mm x 4mm 的微型芯片中。小时候,科学博览会上的陀螺仪总是让我们感到惊讶,因为它们以奇怪的方式移动,甚至似乎违背了重力。 阅读详情

作者:海子
出处:http://www.cnblogs.com/dolphin0520/

 而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。

  今天我们就来讨论一下Callable、Future和FutureTask三个类的使用方法。

目录
一.Callable与Runnable

二.Future

三.FutureTask

四.使用示例

一.Callable与Runnable

先说一下java.lang.Runnable吧,它是一个接口,在它里面只声明了一个run()方法:

public interface Runnable {
    public abstract void run();
}

  由于run()方法返回值为void类型,所以在执行完任务之后无法返回任何结果。

  Callable位于java.util.concurrent包下,它也是一个接口,在它里面也只声明了一个方法,只不过这个方法叫做call():

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

  可以看到,这是一个泛型接口,call()函数返回的类型就是传递进来的V类型。

  那么怎么使用Callable呢?一般情况下是配合ExecutorService来使用的,在ExecutorService接口中声明了若干个submit方法的重载版本:

<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);

  第一个submit方法里面的参数类型就是Callable。

  暂时只需要知道Callable一般是和ExecutorService配合来使用的,具体的使用方法讲在后面讲述。

  一般情况下我们使用第一个submit方法和第三个submit方法,第二个submit方法很少使用。

二.Future

  Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。

  Future类位于java.util.concurrent包下,它是一个接口:

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;
}

  在Future接口中声明了5个方法,下面依次解释每个方法的作用:

cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。

isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。

isDone方法表示任务是否已经完成,若任务完成,则返回true;

get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;

get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。

  也就是说Future提供了三种功能:

  1)判断任务是否完成;

  2)能够中断任务;

  3)能够获取任务执行结果。

  因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了下面的FutureTask。

三.FutureTask

  我们先来看一下FutureTask的实现:

public class FutureTask<V> implements RunnableFuture<V>

  FutureTask类实现了RunnableFuture接口,我们看一下RunnableFuture接口的实现:

public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}

  可以看出RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。所以它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。

  FutureTask提供了2个构造器:

public FutureTask(Callable<V> callable) {
}
public FutureTask(Runnable runnable, V result) {
}

  事实上,FutureTask是Future接口的一个唯一实现类。

四.使用示例

  1.使用Callable+Future获取执行结果

public class Test {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();
        Future<Integer> result = executor.submit(task);
        executor.shutdown();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("主线程在执行任务");

        try {
            System.out.println("task运行结果"+result.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("所有任务执行完毕");
    }
}
class Task implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for(int i=0;i<100;i++)
            sum += i;
        return sum;
    }
}

结果

子线程在进行计算
主线程在执行任务
task运行结果4950
所有任务执行完毕

  2.使用Callable+FutureTask获取执行结果

public class Test {
    public static void main(String[] args) {
        //第一种方式
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        executor.submit(futureTask);
        executor.shutdown();

        //第二种方式,注意这种方式和第一种方式效果是类似的,只不过一个使用的是ExecutorService,一个使用的是Thread
        /*Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        Thread thread = new Thread(futureTask);
        thread.start();*/

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("主线程在执行任务");

        try {
            System.out.println("task运行结果"+futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("所有任务执行完毕");
    }
}
class Task implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for(int i=0;i<100;i++)
            sum += i;
        return sum;
    }
}

 如果为了可取消性而使用 Future 但又不提供可用的结果,则可以声明 Future

Dify 第 2 篇 Dify 插件离线安装 Dify是一个支持插件扩展的AI平台,其插件市场提供5种类型插件(模型、工具、Agent策略、扩展、插件包)。由于默认pip安装速度慢,可通过dify-plugin-repackaging工具将插件转换为离线包(使用阿里云镜像加速)。该工具提供两种方式:1)自备Python环境执行脚本;2)使用Docker环境(推荐)。脚本支持从Dify市场或GitHub下载插件,并重新打包为含依赖的离线包,便于通过"本地插件"方式快速安装。 阅读详情

相关推荐

手把手教你给STM32F103移植LVGL触摸驱动(基于野火开发板,附完整代码)

本文详细介绍了如何在野火STM32F103开发板上移植LVGL触摸驱动,提供从环境准备到代码实现的完整指南。通过XPT2046触摸芯片的底层驱动集成和LVGL输入设备接口配置,开发者可以快速实现触摸功能,并解决常见问题如触摸无响应、坐标偏移等。

weixin_30856725的博客 1021

Callable、Future 和 FutureTask经典讲解以及应用!

Callable、Future 和 FutureTask经典讲解以及应用!🎉

qq_56158663的博客 1032

基于TI MSPM0的PS2双轴按键摇杆模块ADC+GPIO驱动移植实战

本文详细介绍了在TI MSPM0微控制器上驱动PS2双轴按键摇杆模块的完整实战流程。通过SysConfig图形化工具配置ADC与GPIO引脚,并编写了包含ADC采样、按键检测及数据处理的驱动代码,实现了对摇杆X/Y轴模拟量及按键数字量的稳定读取,为嵌入式控制项目提供了可直接移植的解决方案。

weixin_42465140的博客 83

Java异步编程之Future机制原理

一、回顾Runnable和Callable 区别: Callable定义了call()方法,Runnale定义了run()方法。 call()方法可以抛出异常,run()方法无法抛出异常。 Callable有返回值,是泛型的,创建的时候传递进去,执行结束后返回。 Callable执行任务的时候可以通过FutureTask得到任务执行的状态。 联系: Callable的call方法实际执行在R...

qq_41030039的博客 3678

告别密码烦恼:用Windows Server NPS给公司Wi-Fi和有线网加一道MAC地址白名单(附H3C交换机配置)

本文详细介绍了如何利用Windows Server NPS(网络策略服务器)与H3C交换机实现MAC地址白名单认证,为企业Wi-Fi和有线网络提供零密码安全方案。通过配置NPS服务器、网络策略及H3C交换机联调,实现无感知认证体验,降低运维负担,同时满足审计追溯需求。适用于中小企业网络管理,提升安全性与便捷性。

weixin_42535703的博客 367

ros_control硬件接口实战:从零构建机器人控制框架

本文详细介绍了ros_control硬件接口在机器人控制框架中的核心作用与实践方法。通过解析硬件接口类型、实现标准接口、构建主控制循环及自定义功能扩展,帮助开发者从零构建高效的机器人控制系统,提升硬件与ROS的协同效率。

lstm7chronicler的博客 500

Java并发编程:Callable、Future和FutureTask

Java并发编程:Callable、Future和FutureTask   在前面的文章中我们讲述了创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。   这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。   如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。   而自从Java ...

weixin_30621919的博客 2022

SDR 和 DDR 的区别

SDR 和 DDR 的差别,最明显提现在传输速率和频率上。DDR SDRAM与SDRAM的基本结构是相似的,最根本的区别在于DDR 支持在一个时钟周期内传输两次数据,,SDR 只能传输一次数据。

串起点滴 1960

Java异步编程源码及原理解析:Future、FutureTask、@Async、ForkJoin框架、CompletableFuture、Redis队列、Reactive响应式编程的优缺点及适用场景

Java异步编程源码及原理解析 目录 1.Fork-Join 2.FutureTask 3.Async注解介绍 4.CompletableFuture 5.中间件+线程池 会当凌绝顶,一览众山小。 1.Fork-Join框架介绍 从一道面试题讲起:如何使用多线程实现归并排序? public class Solution { private static final ForkJoinPool pool = new ForkJoinPool(4); // N 核心处理器 // 多线程排序

qq_43265673的博客 2487

手把手教你学simulink(24.4)--Simulink在机器人视觉场景下的应用——基于视觉的物体跟踪与抓取

该系统集成了图像处理、目标检测、运动估计、路径规划、抓取控制和视觉反馈等多个功能模块,能够实现实时处理视觉数据、检测并跟踪移动物体、规划最优路径并控制机械臂进行精确抓取。本项目的目标是使用Simulink和MATLAB设计一个基于视觉的物体跟踪与抓取系统,该系统能够实时处理图像数据,检测并跟踪移动物体,规划最优的抓取路径,并控制机械臂进行精确抓取。为了验证系统的性能,我们在Simulink中搭建了基于视觉的物体跟踪与抓取系统的仿真模型。

MHD0815的博客 257

2025机械考研复试面试问题汇总篇(含13门科目),考研机械复试专业面试常见重点问题总结!考研机械复试专业面试准备看这一篇就够了!

(完整版内容:)1.汇集了本科各科的重点知识及多个机械名校800多个常见问题,共8.7万字185页,涵盖机械所以专业课的重点知识和常见问答。 2.涉及机械大类重点科目,包括:材料力学、控制工程、数控技术、机械制造技术基础、理论力学、液压传动、机械设计、机械原理、工程材料、互换性与技术测量、测试技术、汽车理论、程序设计与C语言等13门必修课。

weixin_56510835的博客 1862

Java并发编程之Future原理分析

在Java中,多线程编程是一种常见的编程模式,它允许程序同时执行多个线程,以提高程序的执行效率。然而,如果每个线程都创建和销毁线程,这将带来巨大的开销。为了解决这个问题,Java提供了线程池,它是一个重用的线程集合,可以减少创建和销毁线程的开销。Java并发编程之Future原理是Java线程池中的重要技术。通过使用Future,我们可以查询异步计算的结果,并在计算完成后采取相应的操作。在实现上,Java提供了FutureTask类来支持这一功能,它可以减少我们的工作量并提高代码的可读性。

隐风的博客 625

大厂面经:京东大数据面试题及参考答案(3万字长文)

Kafka是一个开源的分布式流处理平台,由 LinkedIn 开发并在 2011 年贡献给 Apache 软件基金会。高吞吐量:能够处理大量的数据流,适合实时数据管道。持久性:数据存储在磁盘上,确保数据不丢失。容错性:通过数据复制提供高可用性。扩展性:支持水平扩展,易于增加更多节点。Kafka 的核心概念Topic:逻辑上的数据流,可以理解为主题。Producer:生产数据的应用程序。Consumer:消费数据的应用程序。Broker:Kafka 集群中的服务器节点。Partition。

大模型大数据攻城狮的专栏 863

Java的Future机制详解

B图表达的是使用Future模式之后,我们主线程在invoke之后可以立即返回,去做其他的事情,回头再来看看刚才提交的invoke有没有结果。而如果使用第二个构造函数那么最后获取线程实行结果就是参数中的result,接下来让我们看一下FutureTask的run方法。方法能准确地告诉你某个字段相对于对象的起始内存地址的字节偏移量,因为是相对偏移量,所以它其实跟某个具体对象又没什么太大关系,跟class的定义和虚拟机的内存模型的实现细节更相关。get方法有两个,一个是有超时时间设置,另一个没有超时时间设置。

u013950690的博客 3987

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java并发编程:Callable、Future和FutureTask原理解析

返回结果的任务Callable与FutureExecutor框架使用Runnable作为其基本的任务表示形式。Runnable是一种有很大局限的抽象,它不能返回一个值或抛出一个受检查的异常。Runnable接口:public interface Runnable { public abstract void run(); }由于run()方法返回值为void类型,所以在执行完任务之后无法返回

codershamo的博客 2万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android并发编程之白话文详解Future,FutureTask和Callable

说到并发编程,就一定是多个线程并发执行任务。那么并发编程的基础是什么呢?没错那就是Thread了。一个Thread可以执行一个Runnable类型的对象。那么Runnable是什么呢?其实Runnable是一个接口,他只定义了一个方法run(),这个run()方法里就是我们要执行的任务,并且是要被Thread调用的。因此,一个Runnable就可以理解为一个要被执行的任务,而Thread就是一个执

阿拉灯神灯的专栏 1万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

并发编程之Callable、Runnable、Future与FutureTask

并发编程之Callable、Runnable、Future与FutureTask

似霰的博客 1566

一文彻底搞懂:Runnable、Callable、Future、FutureTask 之间的关系

Java并发编程中的Runnable、Callable、Future和FutureTask详解:Runnable是最基础的任务接口,无返回值;Callable是其增强版,支持返回值和异常抛出。Future作为异步结果的凭证,提供任务状态查询和结果获取功能。FutureTask巧妙地将Runnable和Future结合,既能执行任务又能保存结果。线程池的submit()方法会自动将Callable包装成FutureTask执行。这套体系构成了Java异步任务处理的核心模型,FutureTask作为关键桥梁,支

Mark Wu 的博客 1644

Java 并发编程中Callable、Runnable、Future、FutureTask

Java并发编程中的核心组件对比与使用: Runnable和Callable是任务执行接口,前者无返回值,后者支持返回值和异常抛出。Future作为异步计算结果容器,提供任务状态查询和结果获取功能。FutureTask则同时实现了Runnable和Future,兼具任务执行和结果存储能力。关键区别在于:Runnable适合简单任务,Callable用于需要返回值的场景,FutureTask可独立作为可运行的Future对象。使用时需注意避免无限阻塞、正确处理异常并及时释放资源,对于复杂异步场景推荐使用Jav

红血哥 1120

Android并发编程之详解Future,FutureTask和Callable

转自:http://blog.youkuaiyun.com/nugongahou110   从最简单的说起Thread和Runnable   说到并发编程,就一定是多个线程并发执行任务。那么并发编程的基础是什么呢?没错那就是Thread了。一个Thread可以执行一个Runnable类型的对象。那么Runnable是什么呢?其实Runnable是一个接口,他只定义了一个方法run(),这个run()方...

蟹老板的博客 930

并发编程之Callable、Future和FutureTask

1

博客 509

Callable、Future和FutureTask

原文地址:https://www.cnblogs.com/dolphin0520/p/3932921.html 自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。 一.Callable与Runnable   先说一下java.lang.Runnable吧,它是一个接口,在它里面只声明了一个run()方法: public interface Runnable { public abstract void run(); } 由于run()

weixin_37607613的博客 188
上一篇: 并发编程修十一:线程池的使用
下一篇: 并发编程修炼十三:Timer和TimerTask
yjgithub
博客等级 码龄11年 53粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值