首页 > 编程语言 >一文搞懂Java异步编程之FutureTask(转)

一文搞懂Java异步编程之FutureTask(转)

时间:2023-09-28 09:05:44浏览次数:24  
标签:异步 Runnable Java Thread Future 线程 FutureTask 搞懂

背景

Java异步编程的在实际开发中经常被用到,那么异步任务执行结束如何将结果通知到主线程或者其他任务呢?本文不探讨JUC包下的各类锁实现实现的任务同步或者通知。

一、Thread

狭隘的讲Java创建线程的方式只有一种,就是new Thread实例。Thread本身是Runnable的实现并且它定义了Runnable的field,所以支持自定义实现Runnable接口后,在new实例时构造Thread,最终一个新建的线程都需要通过调用start()执行。

这里有一点值得拿出来讲讲,如果直接执行Thread的run(),那么这时候并不是多线程的,它其实就是在主线程中执行了Runnable中定义的普通run方法。

由于Thread没有返回值,异步处理完的结果获取就有点麻烦。到了JDK1.5的时候,Callable和Future被引入,返回线程执行结果。

二、Future与FutureTask

讲到这里终于点题了,Future是一个接口,可以对Runnable或者Callable的task进行取消、判断是否取消、判断是否完成、获取执行结果;执行结果的获取是阻塞,直到task返回结果或者超时当前线程才会继续往下执行。

Future是一个接口,FutureTask是它的实现类,它的继承关系如下,

public class FutureTask<V> implements RunnableFuture<V>
public interface RunnableFuture<V> extends Runnable, Future<V>

 

因此它可以作为Runnable被线程执行

public static void main(String[] args) throws ExecutionException, InterruptedException {
    FutureTask<String> futureTask = new FutureTask<>(() -> {
        System.out.println(Thread.currentThread().getName()); // Thread-0
        System.out.println("Runnable implements"); // Runnable implements
    }, null);
    new Thread(futureTask).start();
    System.out.println(Thread.currentThread().getName()); // main
    String result = futureTask.get();
    System.out.println(result); // null
}

上示例代码,输出内容顺序为 main-》Thread-0-》Runnable implements-》null 。最终输出null是因为FutureTask的构造函数中传入的就是null,如果有需要可以传值给异步任务处理,通过自定义Task类实现Runnable接口,把传值作为field给到Task处理。

小结

Future可以很容易的获得异步执行的结果,并且对任务进行一些操控;get等待结果时会阻塞,所以当任务之间有依赖关系的时候,一个任务依赖另一个任务的结果,可以用Future的get来等待依赖的任务完成的结果。

FutureTask是实现类,有Runnable的特性又有Future的特性,内部包的是Callable ,当然也有接受Runnable的构造器,只是会偷偷把Runnable转成Callable来实现能返回结果的方法。

标签:异步,Runnable,Java,Thread,Future,线程,FutureTask,搞懂
From: https://www.cnblogs.com/ltsgsh/p/17734794.html

相关文章

  • 一文搞懂性能测试
    性能测试概念我们经常看到的性能测试概念,有人或称之为性能策略,或称之为性能方法,或称之为性能场景分类,大概可以看到性能测试、负载测试、压力测试、强度测试等一堆专有名词的解释。针对这些概念,我不知道你看到的时候会不会像我的感觉一样:乱!一个小小的性能测试,就延伸出了这么多的......
  • JAVA代码使用JNI的方式调用C/C++动态库
    JNI(javanativeinterface),通过JNI的方式调用动态库步骤比较麻烦,不用额外引入依赖,对java项目工程依赖侵入为0,类中含有native描述的方法都会与动态库去一一映射,能通过System.load()函数去加载动态库,这种方式主要使用的场景是java写好类(一般不是接口),让C或者C++去实现......
  • Java之包装类的算法小题的练习
     算法小题练习一:需求:键盘录入一些1~10日之间的整数,并添加到集合中。直到集合中所有数据和超过200为止。代码示例:publicclassTest1{publicstaticvoidmain(String[]args){/*键盘录入一些1~10日之间的整数,并添加到集合中。直到集合中所有数据和超......
  • 无涯教程-JavaScript - CHAR函数
    描述CHAR函数返回由数字指定的字符。使用CHAR将可能从其他类型的计算机上的文件中获得的代码页码转换为字符。语法CHAR(number)争论Argument描述Required/OptionalNumber1到255之间的数字,指定所需的字符。该字符来自Windows环境的ANSI字符集。RequiredNotes如......
  • 【Vue】彻底搞懂条件&列表渲染
    hello,我是小索奇哈,精心制作的Vue系列持续发放,涵盖大量的经验和示例,由浅入深进行讲解。本章给大家讲解的是条件&列表渲染,前面的章节已经更新完毕,后面的章节持续输出,有任何问题都可以留言或私信哈,一起加油~条件渲染1.v-if这个指令根据表达式的真假来决定是否渲染元素例如:<divv-if......
  • Java for循环:编程新手的必备技能
    Java for循环和增强的for循环是一种控制流语句,它提供了一种紧凑的方法来迭代值范围。循环重复遍历代码,直到满足特定条件为止。在此期间,Java for循环具有不同类型。for循环增强for循环或foreachfor循环for循环是3个表达式的组合,需要理解才能有效地使用for循环。初始化表达式初......
  • JavaScript解密日记5
    引言:在从事JAVA工作的第五个年头,突然开始对js加密js解密感兴趣。开始了探索的路程1.JavaScript基础知识:JavaScript是一种用于Web开发的脚本语言,它包括以下基础概念:变量(Variables):用于存储数据的容器,可使用var、let或const关键字声明。数据类型(DataTypes):包括数字、字符串、布......
  • java的jdk配置环境变量
    安装JDK选择安装目录安装过程中会出现两次安装提示。第一次是安装jdk,第二次是安装jre。建议两个都安装在同一个java文件夹中的不同文件夹中。(不能都安装在java文件夹的根目录下,jdk和jre安装在同一文件夹会出错)如下图所示 1:安装jdk随意选择目录只需把默认......
  • java.net.ConnectException: Connection refused: no further information
    java.net.ConnectException:Connectionrefused:nofurtherinformation atsun.nio.ch.SocketChannelImpl.checkConnect(NativeMethod)~[na:1.8.0_91] atsun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:717)~[na:1.8.0_91] atio.netty.channe......
  • 无涯教程-JavaScript - VARA函数
    描述VARA函数根据样本估算方差。除数字外,计算中还包括文本和逻辑值,如TRUE和FALSE。语法VARA(value1,[value2]...)争论Argument描述Required/Optionalvalue11to255valueargumentscorrespondingtoasampleofapopulation.RequiredValue2,...OptionalN......