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
相关文章
|
开发工具 git 开发者
Cron表达式每隔两小时执行一次
Cron表达式每隔两小时执行一次
487 1
|
Java BI 图形学
java实现图片压缩功能
java实现图片压缩功能
821 0
|
前端开发 JavaScript UED
前端try和catch
前端try和catch
152 0
|
JSON 缓存 NoSQL
Spring Boot/Spring Cloud中Redis报错Connection reset
本文目录 1. 现象 2. 思路 3. 实现 4. 实验
2267 0
|
5月前
|
开发工具 Android开发 iOS开发
flutter 环境配置
flutter 环境配置
865 63
|
Java 开发者 Spring
CompletableFuture 使用总结
CompletableFuture 使用总结
343 1
|
11月前
|
Java 云计算 微服务
手写@RefreshScope,很简单嘛!
【10月更文挑战第8天】 在微服务架构和云计算时代,动态配置管理变得越来越重要。Spring Cloud提供了@RefreshScope注解,允许我们在不重启应用的情况下,动态刷新配置。但你有没有想过,这个注解是如何实现的呢?本文将带你一起手写一个简化版的@RefreshScope,一探究竟!
221 7
|
存储 Java
【Java】已解决java.util.concurrent.RejectedExecutionException异常
【Java】已解决java.util.concurrent.RejectedExecutionException异常
889 1
|
Java 调度
确保 Java 中三个线程 T1、T2、T3 的顺序
【8月更文挑战第22天】
511 4