Future和CompletableFuture的理解

Future:

一个Future接口表示一个未来可能会返回的结果,它定义的方法有:

get():获取结果(可能会等待)
get(long timeout, TimeUnit unit):获取结果,但只等待指定的时间;
cancel(boolean mayInterruptIfRunning):取消当前任务;
isDone():判断任务是否已完成。
在调用get()时,如果异步任务已经完成,我们就直接获得结果。如果异步任务还没有完成,那么get()会阻塞,直到任务完成后才返回结果。
使用Future获得异步执行结果时,要么调用阻塞方法get(),要么轮询看isDone()是否为true,这两种方法都不是很好,因为主线程也会被迫等待。

CompletableFuture:

使用Future获得异步执行结果时,要么调用阻塞方法get(),要么轮询看isDone()是否为true,这两种方法都不是很好,因为主线程也会被迫等待。
从Java 8开始引入了CompletableFuture,它针对Future做了改进,可以传入回调对象,当异步任务完成或者发生异常时,自动调用回调对象的回调方法
CompletableFuture的优点是:

  • 异步任务结束时,会自动回调某个对象的方法;
  • 异步任务出错时,会自动回调某个对象的方法;
  • 主线程设置好回调后,不再关心异步任务的执行。

CompletableFuture可以指定异步处理流程:

  • thenAccept()处理正常结果;
  • exceptional()处理异常结果;
  • thenApplyAsync()用于串行化另一个CompletableFuture
  • anyOf()allOf()用于并行化多个CompletableFuture

使用 CompletableFuture 的方法

  1. 直接使用 CompletableFuture 提交任务

    • 使用 CompletableFuture.runAsync()CompletableFuture.supplyAsync(),这些方法会使用默认线程池来执行异步任务。
    • 适合快速启动简单的异步操作,不需要额外的线程池管理。
  2. 使用 CompletableFuture 并指定线程池

    • 通过 supplyAsync()runAsync() 的重载版本,接受 Executor 参数,从而使用自定义线程池来执行任务。
    • 适合需要对线程池进行配置和管理的场景,如调整线程数量、队列容量等。
    java复制代码ExecutorService executor = Executors.newFixedThreadPool(10);
    CompletableFuture.supplyAsync(() -> {
        // 执行某些操作
        return result;
    }, executor);
    
  3. 通过线程池中的 submit() 方法获取 CompletableFuture

    • 使用 Executorsubmit() 方法(如 executor.submit()),结合 CompletableFuture 来获取执行结果。
    • 这通常会返回 Future,但可以将结果转换为 CompletableFuture 进行后续处理。
    java复制代码Future<String> future = executor.submit(() -> {
        // 执行某些操作
        return result;
    });
    CompletableFuture<String> completableFuture = CompletableFuture.completedFuture(future.get());
    

异常处理和结果回调

  • 通过 thenApply()thenAccept()exceptionally() 等方法处理结果和异常。
  • CompletableFuture 提供了灵活的方式来组合多个异步操作,使得异步编程更容易。

参考:https://www.cnblogs.com/yaochunhui/p/15543298.html

posted on 2024-10-23 10:54  爱为斯坦  阅读(38)  评论(0编辑  收藏  举报