Future理解

简介: Future理解

Future 是 Java 并发编程中的一个重要接口,它代表了异步计算的结果。当你提交一个任务给线程池或其他执行者时,你会得到一个 Future 对象,它可以用来查询计算是否完成、等待计算结果或取消任务。

Future 原理:

  1. 异步计算

    • Future 允许你异步地执行任务,这意味着你可以立即继续执行其他代码,而不必等待任务完成。
  2. 结果获取

    • 可以通过 Future 接口的 get() 方法来获取任务的结果。如果任务尚未完成,get() 方法会阻塞调用线程直到任务完成。
  3. 取消任务

    • 如果任务尚未开始或正在执行,可以通过 Future 接口的 cancel() 方法来取消任务。
  4. 检查任务状态

    • 可以通过 isDone() 方法来检查任务是否已经完成。

Future 的工作流程:

  1. 提交任务

    • 将一个实现了 CallableRunnable 接口的任务提交给 ExecutorService
  2. 获取 Future

    • 执行任务时,ExecutorService 会返回一个 Future 对象。
  3. 等待结果

    • 调用 Futureget() 方法来等待任务完成并获取结果。如果任务已完成,get() 方法会立即返回结果;如果任务尚未完成,get() 方法会阻塞直到任务完成。
  4. 处理结果

    • 一旦 get() 方法返回结果,就可以对结果进行处理。

Future 的使用场景:

  1. 异步处理

    • 当需要执行长时间运行的任务,并且不想阻塞主线程时。
  2. 并行计算

    • 当需要并行执行多个任务,并且需要在所有任务完成后进行一些操作时。
  3. 任务取消

    • 当需要提供任务取消功能时,可以通过 Future 来实现。

Future 的实现:

Java Future 接口有几个实现类,如 FutureTask,它是 FutureRunnable 的组合,通常用于提交具体任务。

示例代码:

import java.util.concurrent.*;

public class FutureExample {
   
    public static void main(String[] args) throws ExecutionException, InterruptedException {
   
        ExecutorService executor = Executors.newSingleThreadExecutor();

        // 提交一个Callable任务
        Future<String> future = executor.submit(() -> {
   
            // 模拟长时间运行的任务
            Thread.sleep(1000);
            return "Result of the task";
        });

        // 在其他地方继续执行其他任务
        System.out.println("Doing other work while waiting for the result...");

        // 获取任务结果
        String result = future.get(); // 这里会阻塞,直到任务完成
        System.out.println(result);

        // 关闭执行者服务
        executor.shutdown();
    }
}

注意事项:

  • get() 方法可能会抛出 InterruptedException,如果等待结果时当前线程被中断。
  • get() 方法还可能抛出 ExecutionException,如果任务执行时抛出了异常。
  • Future 只能用于一次性的结果获取,一旦结果被获取或任务被取消,Future 就不能再被使用。
  1. 使用 get() 方法的异常处理

    • 当调用 Future.get() 方法时,如果异步任务执行过程中抛出了异常,它会封装在 ExecutionException 中抛出。可以通过捕获 ExecutionException 来处理异常。
      Future<?> future = executor.submit(callableTask);
      try {
             
        future.get(); // 等待任务完成并获取结果
      } catch (InterruptedException e) {
             
        // 处理线程被中断的情况
        Thread.currentThread().interrupt(); // 重置中断状态
      } catch (ExecutionException e) {
             
        // 处理异步任务执行过程中的异常
        Throwable cause = e.getCause(); // 获取实际的异常原因
        // 处理异常原因
      }
      
  2. 使用 CompletableFuture

    • CompletableFutureFuture 的增强版,它提供了更丰富的 API 来处理异步任务,包括异常处理。
      CompletableFuture<Void> future = CompletableFuture.supplyAsync(supplierTask)
        .thenApply(function)
        .thenAccept(consumer)
        .exceptionally(throwable -> {
             
            // 处理异常
            return null; // 返回值可以根据需要定制
        });
      
  3. 链式调用 exceptionally 方法

    • CompletableFuture 的链式调用中,exceptionally 方法可以用来捕获和处理整个链式调用中的异常。
      CompletableFuture<?> future = CompletableFuture.supplyAsync(supplierTask)
        .exceptionally(ex -> {
             
            // 处理异常
            return null; // 返回值可以根据需要定制
        });
      
  4. 使用 try-catch

    • 在调用 Future.get() 时,使用 try-catch 块来捕获和处理可能抛出的 InterruptedExceptionExecutionException
相关文章
|
19天前
|
并行计算 Java 大数据
Callable和Future
Callable和Future
|
2月前
|
并行计算 Java
Future、CompletableFuture概述
Future、CompletableFuture概述
27 0
|
4月前
|
Java
Future:异步任务结果获取
Future:异步任务结果获取
55 0
|
4月前
|
C++
C++Future简单的使用
C++Future简单的使用
40 0
|
12月前
|
消息中间件 Java 中间件
Future and CompletableFuture
Future代表异步执行的结果,也就是说异步执行完毕后,结果保存在Future里, 我们在使用线程池submit()时需要传入Callable接口,线程池的返回值为一个Future,而Future则保存了执行的结果 ,可通过Future的get()方法取出结果,如果线程池使用的是execute(),则传入的是Runnable接口 无返回值。
61 0
|
Java API
Java并发编程-Future系列之Future的介绍和基本用法
Java并发编程-Future系列之Future的介绍和基本用法
176 0
Java并发编程-Future系列之Future的介绍和基本用法
|
Java
Future和Callable学习
通常使用线程池+Runnable的时候,会发现Runnable不能返回值,也就执行的结果情况,同时对于出现异常,我们获取异常信息,进行相应的处理。如果需要返回结果,同时需要进一步加工的时候,就可以考虑使用Future+Callable了。同时接口Future的默认实现是FutureTask,因此对于其实现get()方法,会有一个问题,就是如果前面的任务一旦执行的时间耗时较长的时候,就会出现一直阻塞的状态,此时就会出现排队等待的状态,大大影响其性能。适用场景:当一个线程需要等待另一个线程把某个任务执行完成后它才能继续执行,此时可以使用FutureTask。因为FutureTask基于AQS实现,
88 0
Future和Callable学习
|
存储
多线程 - Callable、Future 和 FutureTask 简单应用(二)
多线程 - Callable、Future 和 FutureTask 简单应用(二)
116 0
多线程 - Callable、Future 和 FutureTask 简单应用(二)
|
Java
多线程 - Callable、Future 和 FutureTask 简单应用(一)
多线程 - Callable、Future 和 FutureTask 简单应用(一)
133 0