futureTask

FutureTask允许异步获取执行结果,通过get()方法实现主线程阻塞,等待任务完成。源码中,state变量在get()调用时起到关键作用,若任务未完成则通过awaitDone()调用LockSupport.park()阻塞。run()方法启动线程,setException()和set(result)更新state并唤醒等待的线程,整个流程与AQS类似。

futureTask可以用来异步获取执行结果,也就是说,业务代码的线程和主线程,可以同时执行,在需要获取执行结果的时候,调用其get()方法,就会阻塞主线程,直到获取到执行结果之后,再继续执行主线程的代码,具体的用法,不再详细叙述

使用

public class FutureTaskTest {
   
   
    public static void main(String[] args) throws Exception{
   
   
        FutureTask<Integer> futureTask = new FutureTask(() -> {
   
   
            System.out.println("测试futureTask");
            TimeUnit.SECONDS.sleep(3);
            return 2;
        });

        new Thread(futureTask).start();
        System.out.println("主线程可以继续执行其他代码...,.");

        System.out.println("模拟现在需要用到线程执行结果:");
        Integer result = futureTask.get();
        System.out.println("获取到执行结果:"+result);
    }
}

测试futureTask
主线程可以继续执行其他代码...,.
模拟现在需要用到线程执行结果:
获取到执行结果:2

这个demo就是模拟futureTask的执行过程,在get()方法被调用之后,如果没有获取到执行结果,最后一句代码是无法执行的,会一直阻塞,直到拿到线程的执行结果,才会继续执行主线程

源码

在futureTask源码中,有一个变量,state

/**
     * The run state of this task, initially NEW.  The run state
     * transitions to a terminal state only in methods set,
     * setException, and cancel.  During completion, state may take on
     * transient values of COMPLETING (while outcome is being set) or
     * INTERRUPTING (only while interrupting the runner to satisfy a
     * cancel(true)). Transitions from these intermediate to final
     * states use cheaper ordered/lazy writes because values are unique
     * and cannot be further modified.
     * 这是官方的注释,并且标明了状态流转的过程
     * Possible state transitions:
     * NEW -> COMPLETING -> NORMAL
     * NEW -> COMPLETING -> EXCEPTIONAL
     * NEW -> CANCELLED
     * NEW -> INTERRUPTING -> INTERRUPTED
     */
    private volatile int state;
    /**
     * 在构造函数中,设置为new
     */
    private static final int NEW          = 0;
    /**
     * 线程正常执行完毕,先通过CAS将state修改为completing
     * 是normal的前一个状态
     */
    private static final int COMPLETING   
### Java FutureTask 的用法与示例 `FutureTask` 是 Java 中的一个类,它实现了 `Future` 和 `Runnable` 接口。它可以用于异步执行任务并返回结果。通过结合 `Callable` 和 `ExecutorService`,可以实现复杂的并发任务管理[^1]。 以下是关于 `FutureTask` 的详细说明和使用示例: #### 什么是 FutureTask? `FutureTask` 是一个可取消的任务,表示一个异步计算的结果。它可以包装 `Callable` 或 `Runnable` 对象,并允许在任务完成后获取其结果。如果任务尚未完成,则调用 `get()` 方法会导致线程阻塞,直到任务完成为止。 #### 创建 FutureTask 可以通过以下两种方式创建 `FutureTask`: 1. 使用 `Callable`:`new FutureTask<>(Callable<V> callable)` 2. 使用 `Runnable` 和 `Result`:`new FutureTask<>(Runnable runnable, V result)` #### 示例代码 下面是一个使用 `FutureTask` 的完整示例: ```java import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class FutureTaskExample { public static void main(String[] args) { // 定义一个 Callable 任务 Callable<Integer> task = () -> { Thread.sleep(2000); // 模拟耗时操作 return 42; // 返回计算结果 }; // 创建 FutureTask 实例 FutureTask<Integer> futureTask = new FutureTask<>(task); // 启动线程执行任务 Thread thread = new Thread(futureTask); thread.start(); try { // 获取任务的执行结果 Integer result = futureTask.get(); // 阻塞直到任务完成 System.out.println("任务结果: " + result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } } ``` #### 注意事项 - 如果任务抛出异常,则调用 `get()` 方法时会抛出 `ExecutionException`,其原因可以通过 `getCause()` 方法获取。 - 如果任务被取消,则调用 `get()` 方法会抛出 `CancellationException`。 #### 解决相关问题 当使用 `FutureTask` 时,可能会遇到一些常见问题,例如: 1. **任务未完成导致阻塞**:确保在调用 `get()` 方法之前任务已经完成,或者设置超时时间以避免无限期等待。 2. **内存泄漏**:如果 `FutureTask` 被长时间持有但未释放,可能导致内存泄漏。因此,在任务完成后应尽快清理资源。 --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值