Java多线程:Future和FutureTask

news2024/11/16 5:31:29

一、Future

Future是一个接口,所有方法如下:

image.png

上源码:

package 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;
}
  • cancel:取消任务(mayInterruptIfRunning是否中断正在执行的任务)。
  • isCancelled:任务是否取消
  • isDone:任务是否执行完成。
  • get:获取任务结果
  • get(long timeout, TimeUnit unit):有等待时间的获取任务结果。

二、FutureTask

FutureTask是一个类,实现了RunnableFuture接口,RunnableFuture接口继承了RunnableFuture,关系图如下:

image.png

FutureTask有两个构造函数:

public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;       // ensure visibility of callable
}

public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;       // ensure visibility of callable
}

第一个构造函数传入一个Callable对象,第二个构造函数传入Runnable对象和一个V类型的对象,然后在函数中将这两个参数构造成一个Callable对象。可见FutureTaskFuture的核心就是要执行Callable并获取返回结果。

FutureTask中的几种状态:

/**
 *
 * 可能的状态转换:
 * NEW -> COMPLETING -> NORMAL
 * NEW -> COMPLETING -> EXCEPTIONAL
 * NEW -> CANCELLED
 * NEW -> INTERRUPTING -> INTERRUPTED
 */
private volatile int state;
private static final int NEW          = 0;
private static final int COMPLETING   = 1;
private static final int NORMAL       = 2;
private static final int EXCEPTIONAL  = 3;
private static final int CANCELLED    = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED  = 6;

查看源码,发现状态共有七种,初始化为NEW,运行时仅在set、setException和cancel方法中会转换为终端状态。终端状态共四种:NORMAL结果正常、EXCEPTIONAL结果异常、CANCELLED任务取消、INTERRUPTED任务中断,可能的状态转换源码中注释已写清楚。

三、示例

Future在线程池中主要做为一个返回(submit方法),用于接收执行完成的结果,FutureTask则是具体实现。
测试代码:

public class ExecutorTest1 {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        ExecutorTest1 test1 = new ExecutorTest1();
        Future<String> futureTest = executorService.submit(() -> test1.say("测试返回值"));
        executorService.shutdown();
    }

    public String say(String a){
        System.out.println("执行了say方法");
        return "test"+a;
    }

}

以上代码,执行了say方法,获取到了futureTest对象,但是futureTest对象不能直接使用,需要调用get方法获取结果,以上代码执行结果:

image.png

获取Future对象结果代码示例:

public class ExecutorTest1 {

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        ExecutorTest1 test1 = new ExecutorTest1();
        Future<String> futureTest = executorService.submit(() -> test1.say("测试返回值"));
        try {
            String s = futureTest.get();
            System.out.println(s);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        executorService.shutdown();
    }

    public String say(String a){
        System.out.println("执行了say方法");
        return "test"+a;
    }

}

可见要执行有返回值的线程,需要用Future来接收。那么FutureTask在哪里使用了呢,在执行方法的时候将传入的Callable对象或者Runnable对象封装成FutureTask对象,源码如下:

public Future<?> submit(Runnable task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<Void> ftask = newTaskFor(task, null);
    execute(ftask);
    return ftask;
}

public <T> Future<T> submit(Runnable task, T result) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task, result);
    execute(ftask);
    return ftask;
}

public <T> Future<T> submit(Callable<T> task) {
    if (task == null) throw new NullPointerException();
    RunnableFuture<T> ftask = newTaskFor(task);
    execute(ftask);
    return ftask;
}

newTaskFor方法如下:

protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
    return new FutureTask<T>(runnable, value);
}

四、结果

Future和FutureTask的核心作用是获取有返回值的线程结果。

Java多线程:Future和FutureTask

Java线程池详解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/190231.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5.3 场效应管的高频等效模型

由于场效应管各级之间存在极间电容&#xff0c;因而其高频响应与晶体管相似。根据场效应管的结构&#xff0c;可得出图5.3.1(a)所示的高频等效模型&#xff0c;大多数场效应管的参数如表1所示。由于一般情况下 rgsr_{gs}rgs​ 和 rdsr_{ds}rds​ 比外接电阻大得多&#xff0c;因…

Lesson 4.5 梯度下降优化基础:数据归一化与学习率调度

文章目录一、数据归一化方法1. 数据归一化计算公式1.1 0-1 标准化1.2 Z-Score 标准化1.3 非线性标准化2. 数据归一化算法执行过程3. 数据归一化算法评价4. Z-Score 标准化算法评价及横向对比二、梯度下降算法优化初阶1. 数据归一化与梯度下降算法优化2. 学习率调度3. 小批量梯度…

RV1126笔记二十六:lvgl移植

若该文为原创文章,转载请注明原文出处。 之前做项目的时候有了解到LVGL这个开源的gui库,有QT仿真过智能家居控制界面,也在STM32上移植过。 趁着过年期间就想着把它移植到自己的开发板上看看能不能正常跑起来。虽说不难,但也花了一些功夫,因此也在这里做下总结。 下载地址…

STC15系列PWM中断控制寄存器介绍以及PWM相关示例

STC15系列PWM中断控制寄存器介绍以及PWM呼吸灯代码实现&#x1f4cc;相关篇《STC15系列PWM功能相关功能寄存器介绍》✨以下数据来源于stc15手册。 &#x1f4d3;增强型PWM波形发生器的中断控制 1.PWM中断优先级控制寄存器:IP2 PPWMFD:PWM异常检测中断优先级控制位。 当PPWMFD…

微信小程序员010宠物交易系统商城系统

宠物交易系统商城系统分为用户小程序端和管理员后台网页端&#xff0c;其中后端是采用java编程语言&#xff0c;mysql数据库&#xff0c;idea开发工具&#xff0c;ssm框架开发&#xff0c;本系统分为用户和管理员两个端&#xff0c;其中用户可以在小程序端进行注册登陆&#xf…

嵌入式Linux从入门到精通之第十节:系统编程之进程

进程的定义 程序:程序是存放在存储介质上的一个可执行文件。进程:进程是程序的执行实例,包括程序计数器、寄存器和变量的当前值。程序是静态的,进程是动态的: 程序是一些指令的有序集合,而进程是程序执行的过程。进程的状态是变化的,其包括进程的创建、调度和消亡。 在…

【微服务】分布式搜索引擎elasticsearch(1)

分布式搜索引擎elasticsearch&#xff08;1&#xff09;1.elasticsearch1.1.了解ES1.1.1.elasticsearch的作用1.1.2.ELK技术栈1.1.3.elasticsearch和lucene1.1.4.为什么不是其他搜索技术&#xff1f;1.1.5.总结1.2.倒排索引1.2.1.正向索引1.2.2.倒排索引1.2.3.正向和倒排1.3.es…

08-linux网络管理-nc命令(TCP|UDP网络联通测试,文件传输,带宽测试)

文章目录1. 安装2. 选项2.1 帮助命令2.2 常用示例- 监听TCP端口&#xff08;默认&#xff09;- 监听UDP端口- 链接TCP端口- 链接UDP端口- 接收数据重定向- 上传数据3. 完整示例3.1 示例1&#xff08;端口联通检查&#xff09;3.2 示例2&#xff08;文件传输&#xff09;3.3 带宽…

Linux权限的基本知识

本文已收录至《Linux知识与编程》专栏&#xff01;作者&#xff1a;ARMCSKGT演示环境&#xff1a;CentOS 7 目录 前言 正文 权限是什么&#xff1f; Linux权限的划分 Linux用户的切换命令 Linux文件权限 Linux文件类型 Linux文件权限 Linux角色划分 文件权限的访问和…

buu [MRCTF2020]keyboard 1

题目描述&#xff1a; 题目分析&#xff1a; 由标题keyboard可知与键盘有关 看到一串数字有重复的&#xff0c;且重复数在1~4之间&#xff0c;符合九键拼音键盘 个数便对应位数 例如&#xff1a;6对应m , 666对应o 所以以上对应下来是 “mobilephond” 试过之后不对&#…

Unity-Tcp-网络聊天功能(一): 基本功能

Protobuff的效率较高。TCP用于延迟不高的游戏效果较好&#xff0c;UDP对开发人员友好&#xff08;对于消息的重发等&#xff0c;降低网络延迟&#xff09;&#xff0c;Websocket在网页端H5端进行通信&#xff0c;1.TCP相关API介绍与服务端编写TCP是面向连接的。因此需要创建监听…

【JavaEE多线程】synchronized原理篇

目录 一、synchronized的优化机制 1)无锁状态 2)偏向锁状态:非必要&#xff0c;不加锁 3)轻量级锁 4)重量级锁&#xff1a;挂起等待 二、锁消除 三、锁粗化 锁的粒度 锁粗化的好处 在这一篇文章当中&#xff0c;我们也提到了synchronized的作用。 Java对于synchroniz…

Python super()函数:调用父类的构造方法

Python 中子类会继承父类所有的类属性和类方法。严格来说&#xff0c;类的构造方法其实就是实例方法&#xff0c;因此毫无疑问&#xff0c;父类的构造方法&#xff0c;子类同样会继承。但我们知道&#xff0c;Python 是一门支持多继承的面向对象编程语言&#xff0c;如果子类继…

『Nonebot 插件编写教程』nonebot2处理消息的完整过程

文章目录前言捕获消息处理消息Bot机器人参数Event事件参数回复消息字符串与Message调用MessageSegment接口前言 前面已经有不止一篇博客教大家如何搭建nonebot2环境了大家可以去专栏查看&#xff0c;这篇博客并不会再次带大家来搭建nonebot2环境&#xff0c;而是着手与插件的编…

【微服务】Sentinel规则持久化

Sentinel 规则持久化 一、修改微服务 修改微服务&#xff0c;让其监听Nacos中的sentinel规则配置。 具体步骤如下&#xff1a; 1.引入依赖 在order-service中引入sentinel监听nacos的依赖&#xff1a; <dependency><groupId>com.alibaba.csp</groupId>…

数据结构实验三: 图的操作与实现

数据结构实验一:线性表,堆栈和队列实现 数据结构实验二 :二叉树的操作与实现 数据结构实验三: 图的操作与实现 数据结构实验四 : 查找和排序算法实现 文章目录一、实验目的&#xff1a;二、使用仪器、器材三、实验内容及原理1、教材P310实验题1&#xff1a;实现图的邻接矩阵和邻…

Springboot扩展点之BeanFactoryPostProcessor

Springboot扩展点之BeanFactoryPostProcessor1.功能特性BeanFactoryPostProcessor的执行是Spring Bean生命周期非常重要的一部分&#xff1b; BeanFactory级别的后置处理器&#xff0c;在Spring生命周期内&#xff0c;org.springframework.beans.factory.config.BeanFactoryPos…

【C语言】10题相关讲解+总结----有用的知识1

总结【C语言】10题&#xff0c;有兴趣的可以看看1.结构体与typedef联系2.结构体中涉及的操作符3.指针数组与数组指针4.数组首元素的作用5.喝汽水问题6.上三角矩阵判定7 矩阵相等判定8.VS调试技巧9.Debug与Release关系10.调整奇数偶数顺序11.有序序列合并1.结构体与typedef联系 …

开发互动直播应用很简单:声网 Android Demo保姆级运行教程

本文作者是来自声网开发者社区的用户“Xiaohua”。 前言 本人在参与《声网开发者漫游指南》期间&#xff0c;通过学习了解和学会跑通声网的实时互动Demo&#xff0c;但因为课程提供的demo是移动端和pc端的&#xff0c;很少接触过&#xff0c;所以只能花点时间学习一下才能运行…

如何屏蔽 iOS 软件自动更新,去除更新通知和标记

如何禁用 iPhone、iPad 软件自动更新。适用于 iOS、iPadOS 和 watchOS&#xff0c;即 iPhone、iPad 和 Apple Watch 通用。 请访问原文链接&#xff1a;https://sysin.org/blog/disable-ios-update/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&a…