【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )

本文涉及的产品
云解析DNS-重点域名监控,免费拨测 20万次(价值200元)
简介: 【Android 异步操作】FutureTask 分析 ( Future 接口解析 | Runnable 接口解析 | Callable 接口解析 )

文章目录

一、Future 接口

1、Future 接口简介

2、取消任务方法

3、Future 接口源码注释

二、Callable 接口

三、Runnable 接口



上一篇博客 【Android 异步操作】AsyncTask 异步任务 ( FutureTask 模拟 AsyncTask 执行过程 | AsyncTask 执行过程回顾 | FutureTask 分析 ) 中 , 使用 FutureTask 模拟 AsyncTask 执行 , 简单介绍了 FutureTask<V> 类 , 和 RunnableFuture<V> 接口 ;


本篇博客将分析 Future 接口 , 和 Runnable 接口 , 以及 FutureTask 的运行机制 ;



相关参考文档 :


FutureTask

RunnableFuture

Future

Runnable

Callable

FutureTask 实现了 RunnableFuture 接口 , RunnableFuture 接口实现了 Future 接口和 Runnable 接口 , FutureTask 创建时传入 Callable 对象 , 该对象的 call() 方法就是在子线程执行的异步方法 ;






一、Future 接口




1、Future 接口简介


Future 作用 : Future 是 异步计算结果 ;



提供了以下方法 :


检查计算是否完成

检查计算是否取消

等待计算完成 , 获取计算结果

取消任务


获取结果有如下两个条件 :


调用 get() 方法获取计算结果

计算必须执行完成 , 否则会阻塞直到计算完成 , 才能解除阻塞

调用 get() 方法获取计算结果 , 如果计算没有完成 , 该方法会阻塞 , 直到计算完成之后 , 阻塞才会解除 , 同时返回执行结果 ;



取消任务执行 : 调用 cancel() 方法 , 可以取消异步任务的执行 ; 如果计算完毕 , 该任务无法被取消 ;


使用 Future 的可取消性 : 如果想要 使用 Future 的可取消的特性 , 不提供可用结果 , 可以将类型声明为 Future<?> , 并返回 null 作为基础任务的结果 ;




2、取消任务方法


boolean cancel(boolean mayInterruptIfRunning) 方法 : 尝试取消任务的执行 ;



① 取消失败 : 如果任务已经完成 , 或 已经被取消 , 或 因为其它原因 不能被取消 , 该尝试可能会失败 ;


② 取消成功 : 如果取消成功 , 并且该任务在取消时还没有开始执行 , 该任务之后也不会被执行 ;


③ boolean mayInterruptIfRunning 参数 : 如果任务已经开始执行 , mayInterruptIfRunning 参数确定 , 在尝试终止任务时 , 该执行任务的线程 , 是否应该被中断 ;


④ 方法返回值 : 该方法返回时有以下行为 ;


在这之后如果调用 isDone() 方法 , 会返回 true , 说明该任务已经执行完成 ;

在这之后如果调用 isCancelled() 方法 , 会返回 true , 表明该任务已经被取消 ;



3、Future 接口源码注释


package java.util.concurrent;
/**
 * Future 是异步计算结果 ; 
 * 提供了以下方法 : 检查计算是否完成 , 检查计算是否取消 , 获取计算结果 , 取消任务 ; 
 * 
 * 获取结果有如下两个条件 : 调用 get() 方法获取计算结果 , 
 * 计算必须执行完成 , 否则会阻塞直到计算完成 , 才能解除阻塞 ; 
 * 
 * 取消任务执行 : 调用 cancel() 方法 , 可以取消异步任务的执行 ; 如果计算完毕 , 该任务无法被取消 ; 
 * 使用 Future 的可取消性 : 如果想要使用 Future 的可取消的特性 , 不提供可用结果 , 
 * 可以将类型声明为 Future<?> , 并返回 null 作为基础任务的结果 ;
 */
public interface Future<V> {
    /**
     * 尝试取消任务的执行 ; 
     * 如果任务已经完成 , 或已经被取消 , 或因为其它原因不能被取消 , 该尝试可能会失败 ;
     * 如果取消成功 , 并且该任务在取消时还没有开始执行 , 该任务之后也不会被执行 ;
     * 如果任务已经开始执行 , mayInterruptIfRunning 参数确定 , 在尝试终止任务时 , 
     * 该执行任务的线程 , 是否应该被中断 ; 
     * 该方法返回时 
     *  - 在这之后如果调用 isDone() 方法 , 会返回 true , 说明该任务已经执行完成 ; 
     *  - 在这之后如果调用 isCancelled() 方法 , 会返回 true , 表明该任务已经被取消 ; 
     *
     * @param mayInterruptIfRunning 
     *    true 执行该任务的线程应该被中断 ; 
     *    false 执行中的线程应该被执行完成 ; 
     * 
     * @return 任务无法取消时会返回 false , 一般是任务已经执行完成 ; 
     *      成功取消任务 , 返回 true ; 
     */
    boolean cancel(boolean mayInterruptIfRunning);
    /**
     * 如果任务在正常完成前被取消 , 就返回 true ;
     */
    boolean isCancelled();
    /**
     * 如果任务执行完毕 , 返回 true ;
     * 影响任务执行的因素 : 
     *  - 正常终止
     *  - 出现异常
     *  - 用户取消 
     * 上述所有情况出现 , 都表示任务执行完毕 ; 
     */
    boolean isDone();
    /**
     * 等待任务完成 , 返回执行结果 ; 
     */
    V get() throws InterruptedException, ExecutionException;
    /**
     * 等待任务完成 , 返回执行结果 ; 
     *
     * @param 最长等待时间
     * @param 等待时间单位
     * @return 任务执行结果 
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}





二、Callable 接口


Callable<V> 简介 : Callable 是一个任务 , 返回 V 类型结果 , 或者 抛出异常 ; 实现类需要实现 call() 方法 , 该方法没有参数 ;



Callable<V> 与 Runnable 对比 :


该 Callable 接口与 Runnable 接口类似 , 两个接口都设计为实现类的对象实例 , 可能都要 在另外的线程执行 ;


Runnable 接口的 run() 方法 不返回返回值 , 不能抛出检查出的异常 ;


Callable<V> 接口的 call() 方法可以 返回返回值 , 可以抛出异常 ;



package java.util.concurrent;
/**
 * Callable<V> 是一个任务 , 返回 V 类型结果 , 或者抛出异常 ; 
 * 实现类需要实现 call() 方法 , 该方法没有参数 ; 
 * 
 * 该 Callable<V> 接口与 Runnable 接口类似 , 
 * 两个接口都设计为实现类的对象实例 , 可能都要在另外的线程执行 ; 
 * 
 * Runnable 接口的 run() 方法不返回返回值 , 不能抛出检查出的异常 ; 
 */
@FunctionalInterface
public interface Callable<V> {
    /**
     * 计算出一个结果 , 如果无法完成 , 抛出异常 ; 
     */
    V call() throws Exception;
}




三、Runnable 接口


Runnable 接口作用 : Runnable 接口的实现类实例 , 需要在一个线程中被执行 ; 该实现类必须实现 run() 方法 , 该方法返回值和参数都是 void ;



Runnable 接口设计 :


设计原则 : 该接口被设计为 , 为那些处于活动状态的对象 , 并且这些对象想要执行代码 , 提供一个通用协议 ;


如 : Thread 类实现了 Runnable 方法 ;


活动状态 : 处于活动状态的含义是 , 线程已经被开始了 , 还不能被停止 , 如果想要执行代码 , 必须在其它线程中执行 ;



创建线程优先策略 :


创建线程 : Runnable 为类提供了不需要继承 Thread 类 , 之外的活动的途径 ; 一个类实现了 Runnable 接口 , 在不继承 Thread 的前提下运行 , 方法是将其传入 Thread 构造函数 ;


推荐方案 :在大部分情况下 , 如果你只打算去覆盖 run 方法 , 并且没有其它的方法 , 应该使用 Runnable 接口 , 不建议使用 Thread 类 ;



不要轻易去继承一个类 , 除非开发者想要去修改或者增强父类的某些行为 ;



/**
 * Runnable 接口的实现类实例 , 需要在一个线程中被执行 ; 
 * 该实现类必须实现 run() 方法 , 该方法返回值和参数都是 void ; 
 * 
 * 该接口被设计为 , 为那些处于活动状态的对象 , 并且这些对象想要执行代码 , 提供一个通用协议 ; 
 * 如 : Thread 类实现了 Runnable 方法 ; 
 * 处于活动状态的含义是 , 线程已经被开始了 , 还不能被停止 , 如果想要执行代码 , 必须在其它线程中执行 ; 
 * 
 * 另外 , Runnable 为类提供了不需要继承 Thread 类 , 之外的活动的途径 ; 
 * 一个类实现了 Runnable 接口 , 在不继承 Thread 的前提下运行 , 方法是将其传入 Thread 构造函数 ; 
 * 在大部分情况下 , 如果你只打算去覆盖 run 方法 , 并且没有其它的方法 , 
 * 应该使用 Runnable 接口 , 不建议使用 Thread 类 ; 
 * 
 * 类不应该继承一个类 , 除非开发者想要去修改或者增强父类的某些行为 , 这是很重要的 ; 
 */
@FunctionalInterface
public interface Runnable {
    /**
     * 当一个对象实现了 Runnable 接口 , 用于创建一个线程时 , 
     * 启动线程会在该线程中 , 调用该对象的 run() 方法 ; 
     * 
     * run() 方法的通用规则是 , 在该方法中可以执行任何操作 ; 
     */
    public abstract void run();
}


目录
相关文章
|
2月前
|
数据采集 监控 API
告别手动埋点!Android 无侵入式数据采集方案深度解析
传统的Android应用监控方案需要开发者在代码中手动添加埋点,不仅侵入性强、工作量大,还难以维护。本文深入探讨了基于字节码插桩技术的无侵入式数据采集方案,通过Gradle插件 + AGP API + ASM的技术组合,实现对应用性能、用户行为、网络请求等全方位监控,真正做到零侵入、易集成、高稳定。
461 33
|
6月前
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
276 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
9月前
|
数据采集 前端开发 JavaScript
金融数据分析:解析JavaScript渲染的隐藏表格
本文详解了如何使用Python与Selenium结合代理IP技术,从金融网站(如东方财富网)抓取由JavaScript渲染的隐藏表格数据。内容涵盖环境搭建、代理配置、模拟用户行为、数据解析与分析等关键步骤。通过设置Cookie和User-Agent,突破反爬机制;借助Selenium等待页面渲染,精准定位动态数据。同时,提供了常见错误解决方案及延伸练习,帮助读者掌握金融数据采集的核心技能,为投资决策提供支持。注意规避动态加载、代理验证及元素定位等潜在陷阱,确保数据抓取高效稳定。
271 17
|
9月前
|
XML JavaScript Android开发
【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
本文总结了Android中几种常用的网络技术,包括WebView、HttpURLConnection、OKHttp和XML的Pull解析方式。每种技术都有其独特的特点和适用场景。理解并熟练运用这些技术,可以帮助开发者构建高效、可靠的网络应用程序。通过示例代码和详细解释,本文为开发者提供了实用的参考和指导。
301 15
|
9月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
9月前
|
消息中间件 JavaScript 前端开发
最细最有条理解析:事件循环(消息循环)是什么?为什么JS需要异步
度一教育的袁进老师谈到他的理解:单线程是异步产生的原因,事件循环是异步的实现方式。 本质是因为渲染进程因为计算机图形学的限制,只能是单线程。所以需要“异步”这个技术思想来解决页面阻塞的问题,而“事件循环”是实现“异步”这个技术思想的最主要的技术手段。 但事件循环并不是全部的技术手段,比如Promise,虽然受事件循环管理,但是如果没有事件循环,单一Promise依然能实现异步不是吗? 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您
|
存储 Linux API
深入探索Android系统架构:从内核到应用层的全面解析
本文旨在为读者提供一份详尽的Android系统架构分析,从底层的Linux内核到顶层的应用程序框架。我们将探讨Android系统的模块化设计、各层之间的交互机制以及它们如何共同协作以支持丰富多样的应用生态。通过本篇文章,开发者和爱好者可以更深入理解Android平台的工作原理,从而优化开发流程和提升应用性能。
|
调度 开发者
核心概念解析:进程与线程的对比分析
在操作系统和计算机编程领域,进程和线程是两个基本而核心的概念。它们是程序执行和资源管理的基础,但它们之间存在显著的差异。本文将深入探讨进程与线程的区别,并分析它们在现代软件开发中的应用和重要性。
447 4
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
11月前
|
人工智能 供应链 搜索推荐
中国CRM市场深度分析:主流供应商排名与特点解析
随着中国企业数字化转型的深入,CRM(客户关系管理)软件市场迅速发展,形成了多个优秀解决方案提供商。销售易、纷享销客、明源云客、金蝶云之家、简道云、红圈营销和爱客CRM等供应商各具特色。销售易在大型企业市场表现突出,提供全链路营销销售一体化及强大的AI能力;纷享销客以易用性和高性价比著称,适合中小企业;明源云客专注房地产行业,提供全流程解决方案;金蝶云之家与ERP系统深度整合,适合传统制造业;简道云是低代码平台,灵活性高;红圈营销专注零售业,支持全渠道营销;爱客CRM则主打智能营销功能。企业在选择CRM时需综合考虑实施难度、价格定位、技术支持等因素,并结合自身需求进行试用和调研,确保选择最适合

推荐镜像

更多