目录
暂无数据

CompletableFuture

boven 2023年03月28日 17:54:53 0 1759

异步编程CompletableFuture的使用及应用

什么是异步编程?

异步编程是一种编程范式,它可以让程序在执行某些耗时或依赖外部资源的任务时,不阻塞当前线程,而是继续执行其他任务,从而提高程序的效率和响应性。异步编程的优点有:

  • 可以充分利用多核处理器和网络资源,提高系统的吞吐量和并发能力
  • 可以避免线程切换和同步的开销,减少系统的资源消耗
  • 可以提升用户体验,让用户感觉程序更流畅和快速

异步编程的缺点有:

  • 代码逻辑更复杂,需要处理回调、异常、状态等问题
  • 调试和测试更困难,需要跟踪异步任务的执行过程和结果
  • 与同步编程的习惯和模式不兼容,需要学习新的思维方式和工具

什么是CompletableFuture?

CompletableFuture是Java 8引入的一个类,它实现了Future和CompletionStage两个接口,可以用来表示一个异步计算的结果。CompletableFuture相比于传统的Future,有以下特点:

  • 支持手动完成,可以在任何线程中调用complete或completeExceptionally方法来设置异步任务的结果或异常
  • 支持非阻塞调用,可以在异步任务完成后执行指定的回调函数,无需等待或轮询
  • 支持链式调用,可以将多个异步任务串联起来,形成一个复杂的异步流程
  • 支持组合调用,可以将多个异步任务合并起来,实现并行、分支、聚合等逻辑
  • 支持异常处理,可以在异步任务出现异常时执行指定的处理函数,或者将异常传递给下游的异步任务

如何使用CompletableFuture?

创建CompletableFuture

创建一个CompletableFuture对象有以下几种方式:

  • 使用无参构造函数创建一个空的CompletableFuture对象,然后在适当的时机调用complete或completeExceptionally方法来设置结果或异常
  • 使用静态方法runAsync或supplyAsync创建一个由指定的Runnable或Supplier执行的异步任务,并返回一个对应的CompletableFuture对象
  • 使用静态方法completedFuture创建一个已经完成并包含指定结果的CompletableFuture对象
  • 使用静态方法failedFuture创建一个已经完成并包含指定异常的CompletableFuture对象

例如:

// 创建一个空的CompletableFuture对象
CompletableFuture<String> future = new CompletableFuture<>();
// 创建一个由Runnable执行的异步任务,并返回一个CompletableFuture<Void>对象
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> {
System.out.println("Hello, world!");
});

// 创建一个由Supplier执行的异步任务,并返回一个CompletableFuture<String>对象
CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
return "Hello, world!";
});

// 创建一个已经完成并包含"Hello, world!"结果的CompletableFuture对象
CompletableFuture<String> future3 = CompletableFuture.completedFuture("Hello, world!");

// 创建一个已经完成并包含RuntimeException异常的CompletableFuture对象
CompletableFuture<String> future4 = CompletableFuture.failedFuture(new RuntimeException("Something went wrong"));
获取CompletableFuture的结果

获取一个CompletableFuture对象的结果有以下几种方式:

  1. get()方法

get()方法是最简单的一种方式,它会阻塞当前线程,直到CompletableFuture完成,并返回结果。如果CompletableFuture发生异常,get()方法会抛出ExecutionException。例如:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); try { String result = future.get(); // 阻塞,等待结果 System.out.println(result); // 输出Hello } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
  1. get(long timeout, TimeUnit unit)方法

get(long timeout, TimeUnit unit)方法和get()方法类似,但是它可以设置一个超时时间,如果在指定的时间内CompletableFuture没有完成,get()方法会抛出TimeoutException。例如:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { try { Thread.sleep(5000); // 模拟耗时操作 } catch (InterruptedException e) { e.printStackTrace(); } return "Hello"; }); try { String result = future.get(3, TimeUnit.SECONDS); // 设置超时时间为3秒 System.out.println(result); // 不会执行到这里,因为会超时 } catch (InterruptedException | ExecutionException | TimeoutException e) { e.printStackTrace(); // 输出java.util.concurrent.TimeoutException }
  1. join()方法

join()方法和get()方法很像,但是它不会抛出任何异常,而是直接将异常包装成CompletionException。例如:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { throw new RuntimeException("Something went wrong"); // 模拟异常 }); String result = future.join(); // 不会抛出异常,而是返回一个CompletionException System.out.println(result); // 输出java.util.concurrent.CompletionException: java.lang.RuntimeException: Something went wrong
  1. thenApply(Function<? super T,? extends U> fn)方法

thenApply(Function<? super T,? extends U> fn)方法可以用来对CompletableFuture的结果进行转换,它接受一个Function作为参数,返回一个新的CompletableFuture。例如:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); CompletableFuture<Integer> newFuture = future.thenApply(s -> s.length()); // 对结果进行转换,返回一个新的CompletableFuture int length = newFuture.join(); // 获取转换后的结果 System.out.println(length); // 输出5
  1. thenAccept(Consumer<? super T> action)方法

thenAccept(Consumer<? super T> action)方法可以用来对CompletableFuture的结果进行消费,它接受一个Consumer作为参数,返回一个新的CompletableFuture。例如:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); future.thenAccept(s -> System.out.println(s)); // 对结果进行消费,输出Hello
  1. thenRun(Runnable action)方法

thenRun(Runnable action)方法可以用来在CompletableFuture完成后执行一个动作,它接受一个Runnable作为参数,返回一个新的CompletableFuture。例如:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello"); future.thenRun(() -> System.out.println("Done")); // 在完成后执行一个动作,输出Done

评论区

登录后参与交流、获取后续更新提醒

联系我

Email:769145832@qq.com

QQ:769145832

Blog

这是我的个人博客、会分享关于编程、写作、思考相关的任何内容,希望可以给来到这儿的人有所帮助...