FutureTask通常如何使用?

FutureTask 是一种有用的工具,用于管理并发编程中可取消的、可监听的任务。它通常被用来包装 CallableRunnable 对象,并在单独的线程中执行这些任务。以下是一些使用 FutureTask 的典型场景和步骤:

1. 包装 CallableRunnable

下面是基本的包装 CallableRunnable 的方法:

java 复制代码
// 使用 Callable
Callable<Integer> callable = () -> {
    // 模拟长时间的任务
    Thread.sleep(1000);
    return 123;
};

FutureTask<Integer> futureTask = new FutureTask<>(callable);

// 使用 Runnable
Runnable runnable = () -> {
    // 模拟长时间的任务
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
};
FutureTask<Void> futureTask2 = new FutureTask<>(runnable, null);

2. 提交任务

可以通过 ThreadExecutorService 提交 FutureTask 并执行任务:

通过 Thread
java 复制代码
Thread thread = new Thread(futureTask);
thread.start();
通过 ExecutorService
java 复制代码
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(futureTask);
executor.shutdown();

3. 获取结果

使用 FutureTaskget 方法可以获取任务的执行结果:

java 复制代码
try {
    Integer result = futureTask.get();
    System.out.println("Result: " + result);
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

如果需要带超时限制的获取,可以使用带超时参数的 get 方法:

java 复制代码
try {
    Integer result = futureTask.get(500, TimeUnit.MILLISECONDS);
    System.out.println("Result with timeout: " + result);
} catch (TimeoutException e) {
    System.out.println("Task timed out");
} catch (InterruptedException | ExecutionException e) {
    e.printStackTrace();
}

4. 取消任务

可以使用 cancel 方法取消任务,如果任务正在运行,你可以选择是否允许中断:

java 复制代码
boolean mayInterruptIfRunning = true;
futureTask.cancel(mayInterruptIfRunning);

if (futureTask.isCancelled()) {
    System.out.println("Task was cancelled");
} else {
    System.out.println("Task was not cancelled");
}

5. 完整示例

下面是一个完整的示例,展示如何使用 FutureTask 包装一个 Callable 任务,并通过 ExecutorService 提交任务执行,同时获取结果并处理取消:

java 复制代码
import java.util.concurrent.*;

public class FutureTaskExample {
    public static void main(String[] args) {
        // 创建一个 Callable 对象
        Callable<Integer> callable = () -> {
            System.out.println("Task started");
            Thread.sleep(2000); // 模拟长时间任务
            System.out.println("Task completed");
            return 123;
        };

        // 创建 FutureTask
        FutureTask<Integer> futureTask = new FutureTask<>(callable);

        // 使用 ExecutorService 提交 FutureTask
        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.submit(futureTask);

        // 主线程可以执行其他任务
        System.out.println("Main thread is doing something else");

        try {
            // 获取任务的结果
            Integer result = futureTask.get(1, TimeUnit.SECONDS);
            System.out.println("Result from FutureTask: " + result);
        } catch (InterruptedException e) {
            System.out.println("Task was interrupted");
        } catch (ExecutionException e) {
            System.out.println("Task encountered an execution exception");
        } catch (TimeoutException e) {
            System.out.println("Task timed out");
            futureTask.cancel(true); // 取消任务
            System.out.println("Task was cancelled: " + futureTask.isCancelled());
        } finally {
            // 关闭 Executor 服务
            executor.shutdown();
        }
    }
}

在这个示例中,FutureTask 包装一个 Callable 对象,并由 ExecutorService 执行。主线程可以执行其他任务,并通过 futureTask.get() 方法获取任务结果。超时发生时任务会被取消。

相关推荐
圆山猫11 分钟前
[Virtualization](四):Linux KVM/RISC-V 的 vCPU 运行路径
java·linux·risc-v
微学AI43 分钟前
一根针指向所有方向:挂谷猜想对 LLM Agent 技能-记忆架构的启示
开发语言·人工智能·架构·挂谷猜想
城管不管1 小时前
ReAct、Plan-and-Execute、Reflection 三大智能 Agent 范式核心区别
java·人工智能·算法·spring·ai·动态规划
IT小白杨1 小时前
从环境制备到自动化工作流:多账号运营的工程化架构拆解
java·经验分享·自动化·安全架构·指纹浏览器
豆瓣鸡1 小时前
算法日记 - Day3
java·开发语言·算法
萧瑟余晖2 小时前
Java深入解析篇九之NIO详解
java·网络·nio
韭菜炒鸡肝天2 小时前
VTK开发笔记(一):VTK介绍,Qt..+VSx+VTK.编译
开发语言·笔记·qt
The Chosen One9852 小时前
高进度算法模板速记(待完善)
java·前端·算法
Aaron - Wistron3 小时前
Web API C# (Furion版)带 单元测试
开发语言·后端·c#
Dxy12393102164 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python