【亮剑】Java中的`Future`接口代表异步计算结果,常与`ExecutorService`配合启动任务并获取结果

简介: 【4月更文挑战第30天】Java中的`Future`接口代表异步计算结果,常与`ExecutorService`配合启动任务并获取结果。`Future`接口提供`isDone()`、`get()`、`get(timeout, unit)`和`cancel(mayInterruptIfRunning)`等方法。`FutureTask`是`Future`的实现类,可作为`Runnable`执行并返回结果。

一、Future 接口与任务机制概述

在并发编程中,我们经常需要对异步计算的结果进行操作。Java中的Future接口是一个代表异步计算结果的接口,它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算结果。Future接口通常与ExecutorService一起使用,以启动异步任务并获取其结果。

Future接口的主要方法包括:

  • boolean isDone(): 判断任务是否已经完成。
  • T get(): 获取异步操作的结果,如果任务未完成则阻塞直到任务完成。
  • T get(long timeout, TimeUnit unit): 获取异步操作的结果,如果在指定的超时时间内任务未完成,则抛出TimeoutException
  • void cancel(boolean mayInterruptIfRunning): 取消任务执行,如果任务正在执行,根据参数决定是否中断执行。

Future接口的实现类FutureTask是一个更加具体的实现,它可以被ExecutorService执行,也可以作为Callable接口的返回结果。

二、FutureTask 的实现原理

FutureTaskFuture接口的实现类,它实现了RunnableFuture接口,这意味着它可以作为Runnable被线程执行,同时可以返回执行结果。FutureTask内部包含了一个Callable任务和一个volatile状态标志位,用于表示任务的状态(尚未初始化、正常执行、取消执行或执行完毕)。

FutureTask的核心方法包括:

  • run(): 执行任务,如果成功完成,则设置结果;如果抛出异常,则设置异常。
  • get(): 获取任务的结果,如果任务未完成,则等待任务完成。
  • cancel(): 取消任务,如果任务尚未开始,则直接设置状态为取消;如果任务已经开始,则可能中断执行。

FutureTask的实现原理主要依赖于内部的锁和条件变量来保证线程安全和同步。当调用get()方法时,如果任务未完成,当前线程会被挂起,直到任务完成或者被取消。当任务完成或者被取消后,条件变量会通知所有等待的线程。

三、FutureTask 的使用方法

下面通过一个简单的例子来说明如何使用FutureTask

  1. 创建一个Callable任务:
class MyCallable implements Callable<Integer> {
   
    @Override
    public Integer call() throws Exception {
   
        // 模拟耗时操作
        Thread.sleep(2000);
        return 1 + 1;
    }
}
  1. 创建一个FutureTask并执行:
public class FutureTaskDemo {
   
    public static void main(String[] args) throws InterruptedException, ExecutionException {
   
        // 创建 Callable 任务
        MyCallable myCallable = new MyCallable();
        // 创建 FutureTask
        FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
        // 创建线程并启动
        Thread thread = new Thread(futureTask);
        thread.start();
        // 获取任务结果
        Integer result = futureTask.get();
        System.out.println("任务结果:" + result);
    }
}

在这个例子中,我们首先创建了一个MyCallable任务,然后将其封装到一个FutureTask中。接着,我们创建了一个线程来执行这个FutureTask。最后,我们通过调用futureTask.get()方法来获取任务的结果。

总结:

本文介绍了Future接口和FutureTask的实现原理及使用方法。通过使用FutureFutureTask,我们可以方便地在多线程环境下处理异步任务的结果。希望本文对你有所帮助!

相关文章
|
14天前
|
JSON Java Apache
非常实用的Http应用框架,杜绝Java Http 接口对接繁琐编程
UniHttp 是一个声明式的 HTTP 接口对接框架,帮助开发者快速对接第三方 HTTP 接口。通过 @HttpApi 注解定义接口,使用 @GetHttpInterface 和 @PostHttpInterface 等注解配置请求方法和参数。支持自定义代理逻辑、全局请求参数、错误处理和连接池配置,提高代码的内聚性和可读性。
|
5天前
|
Java
在Java中,接口之间可以继承吗?
接口继承是一种重要的机制,它允许一个接口从另一个或多个接口继承方法和常量。
22 1
|
15天前
|
Java
java线程接口
Thread的构造方法创建对象的时候传入了Runnable接口的对象 ,Runnable接口对象重写run方法相当于指定线程任务,创建线程的时候绑定了该线程对象要干的任务。 Runnable的对象称之为:线程任务对象 不是线程对象 必须要交给Thread线程对象。 通过Thread的构造方法, 就可以把任务对象Runnable,绑定到Thread对象中, 将来执行start方法,就会自动执行Runable实现类对象中的run里面的内容。
31 1
|
21天前
|
NoSQL Java 调度
Java调度任务如何保证相同任务在一个周期里只执行一次?
【10月更文挑战第29天】Java调度任务如何保证相同任务在一个周期里只执行一次?
57 6
|
20天前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
44 4
|
19天前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
40 2
|
21天前
|
存储 NoSQL Java
Java调度任务如何使用分布式锁保证相同任务在一个周期里只执行一次?
【10月更文挑战第29天】Java调度任务如何使用分布式锁保证相同任务在一个周期里只执行一次?
57 1
|
Java
Java接口和抽象类
Java接口和抽象类
90 0
|
3月前
|
设计模式 Java
【惊天揭秘】Java编程绝技大曝光:接口、抽象类、静态类与非静态类的神秘面纱终被揭开!
【8月更文挑战第22天】Java支持面向对象编程,通过接口、抽象类、静态类(如枚举与工具类)及普通类实现设计原则。接口定义行为规范,允许多重继承;抽象类含未实现的抽象方法,需子类完成;静态类常为工具类,提供静态方法;普通类则实例化对象。恰当运用这些结构能提升程序质量。
40 2
|
6月前
|
设计模式 搜索推荐 Java
java接口和抽象类的区别,以及使用选择
java接口和抽象类的区别,以及使用选择
80 0
下一篇
无影云桌面