Java进阶篇--线程池之FutureTask

目录

FutureTask简介

FutureTask的基本使用

FutureTask的应用场景


FutureTask简介

FutureTask是Java中的一个类,用于表示可获取结果的异步任务。它实现了java.util.concurrent.Future接口,提供了启动和取消异步任务、查询任务是否已完成以及获取最终结果的方法。通过调用get()方法可以获取异步任务的结果,但会阻塞当前线程直至任务执行结束。一旦任务执行结束,任务不能重新启动或取消,除非调用runAndReset()方法。在FutureTask的源码中定义了多种状态,包括

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;

根据FutureTask.run()方法的执行的时机,FutureTask分为了3种状态:

1、未启动状态:指的是在创建FutureTask后,但尚未执行FutureTask.run()方法之前,FutureTask处于未启动状态。

2、已启动状态:指的是FutureTask.run()方法正在被执行的过程中,此时FutureTask处于已启动状态。

3、已完成状态:包括了三种情况:

  • FutureTask.run()方法执行结束;
  • 调用FutureTask.cancel(…)方法取消任务;
  • 在执行任务期间抛出异常。

以上三种情况都属于FutureTask的已完成状态。

对于FutureTask的get()方法和cancel()方法,它们在不同状态下的行为总结如下:

1、get方法:

  • 当FutureTask处于未启动或已启动状态时,执行FutureTask.get()方法将导致调用线程阻塞,直到任务执行完成并返回结果。
  • 如果FutureTask处于已完成状态,调用FutureTask.get()方法将立即返回结果或者抛出异常。

2、cancel方法:

  • 当FutureTask处于未启动状态时,执行FutureTask.cancel()方法将任务标记为已取消,但不会影响当前未启动的任务。
  • 当FutureTask处于已启动状态时,执行FutureTask.cancel(true)方法将以中断线程的方式来阻止任务继续进行,如果执行FutureTask.cancel(false)将不会对正在执行任务的线程有任何影响,任务会继续执行直至结束。
  • 当FutureTask处于已完成状态时,执行FutureTask.cancel(…)方法将返回false,表示无法取消已经完成的任务。

FutureTask的基本使用

FutureTask除了实现了Future接口,还实现了Runnable接口,这使得它既可以作为一个异步任务,也可以作为一个可执行的任务被线程执行。因此,它可以交给Executor执行,也可以由调用的线程直接执行(FutureTask.run())。另外,通过ExecutorService的submit()方法也可以返回一个FutureTask对象,然后可以通过FutureTask.get()或者FutureTask.cancel方法获取结果或取消任务的执行。

以下是一个简单的示例,演示了如何使用FutureTask来实现多线程任务的协调和管理,

import java.util.concurrent.*;

public class main {

    public static void main(String[] args) {
        // 创建一个FutureTask对象
        FutureTask<Integer> futureTask = new FutureTask<>(() -> {
            // 模拟一个耗时的任务,这里使用Thread.sleep来模拟
            Thread.sleep(2000);
            return 42; // 返回结果
        });

        // 创建一个线程池
        ExecutorService executor = Executors.newFixedThreadPool(1);

        // 使用线程池执行FutureTask
        executor.execute(futureTask);

        // 在主线程中可以做一些其他的事情

        try {
            // 获取FutureTask的结果,如果任务还未完成,则会阻塞当前线程直到任务完成
            int result = futureTask.get();
            System.out.println("任务执行结果:" + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        // 关闭线程池
        executor.shutdown();
    }
}

在这个示例中,我们创建了一个FutureTask对象来执行一个耗时的任务,然后将它交给线程池来执行。在主线程中,我们可以做一些其他的事情,然后通过futureTask.get()方法来获取任务的执行结果。如果任务还未完成,get()方法会阻塞当前线程直到任务完成。

这个示例展示了如何使用FutureTask来实现异步任务的执行和结果获取,同时也展示了使用ExecutorService来执行线程任务,并在任务完成后关闭线程池。

FutureTask的应用场景

在实际应用中,FutureTask通常用于以下场景:

  • 需要等待其他线程执行完毕后再继续执行:通过FutureTask可以将需要等待的任务封装起来,然后在需要等待的地方调用其get()方法,当前线程就会阻塞,直到任务执行完毕并返回结果。
  • 多个线程执行同一个任务的控制:可以使用FutureTask来保证多个线程对同一个任务的执行是有序的,例如只允许一个线程执行任务,其他线程需要等待任务执行完毕后才能继续。

总的来说,FutureTask提供了一种方便的方式来管理异步任务的执行和获取结果,同时也可以用于多线程任务的协调与控制。当需要在多线程环境下进行任务调度和管理时,FutureTask是一个非常有用的工具。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
FutureTask是一个具体的实现类,它可以在线程池中使用。当我们使用线程池的submit方法提交一个任务时,返回的是一个Future的实现,而这个实现就是FutureTask的一个具体实例。FutureTask实现了RunnableFuture接口,而RunnableFuture接口继承了Runnable和Future接口,所以FutureTask既是Runnable,也是Future。这意味着我们可以将FutureTask作为一个任务提交给线程池,并且可以通过Future接口的方法来获取任务的执行结果或者取消任务的执行。FutureTask是可取消的异步任务,可以通过调用cancel方法来取消任务的执行。当任务执行完成后,我们可以通过调用get方法来获取任务的执行结果。需要注意的是,如果任务还没有完成,调用get方法将会阻塞调用线程,直到任务完成。另外,一旦任务执行完成,就不能重新开始或取消任务,但可以通过调用runAndReset方法来重置任务的状态并重新执行。所以,FutureTask可以在线程池中用来执行异步任务,并且可以方便地获取任务的执行结果或者取消任务的执行。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* [【第十二篇】Java 线程池FutureFutureTask【重点】](https://blog.csdn.net/weixin_42039228/article/details/123198358)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [深入理解并发编程之线程池FutureTask](https://blog.csdn.net/qq_19586549/article/details/122980971)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

正在奋斗的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值