当前位置: 首页 > news >正文

CompletableFuture的基础用法介绍

CompletableFuture 基础用法介绍




第一章 创建过程

第01节 创建正常情况下已完成的Future

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 创建一个已完成的 CompletableFuture 的对象CompletableFuture<String> future = CompletableFuture.completedFuture("HelloWorld");// 获取到 CompletableFuture 的结果String content = future.get();// 输出结果System.out.println(content);}
}

运行结果

HelloWorld




第02节 创建异常情况下已完成的Future

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 创建一个已完成的 CompletableFuture 的对象CompletableFuture<String> future = CompletableFuture.failedFuture(new Throwable("我异常了"));// 获取到 CompletableFuture 的结果String content = future.get();// 输出结果System.out.println(content);}
}

运行结果

Exception in thread “main” java.util.concurrent.ExecutionException: java.lang.Throwable: 我异常了
at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:396)
at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2073)
at com.completable.completable.Demo.main(Demo.java:13)
Caused by: java.lang.Throwable: 我异常了
at com.completable.completable.Demo.main(Demo.java:10)




第03节 异步执行任务 无返回

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 异步执行任务, 无返回。future 内部消化CompletableFuture<Void> future = CompletableFuture.runAsync(new Runnable() {@Overridepublic void run() {System.out.println("我是一个异步执行的任务, 在内部自己完成消化, 不会返回给外部使用, 本质就是一个异步线程");}});// 调用此方法, 完成上面的异步执行。如果不调用, 则不会显示结果future.get();}
}

运行结果

我是一个异步执行的任务, 在内部自己完成消化, 不会返回给外部使用, 本质就是一个异步线程




第04节 异步执行任务 有返回

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 异步执行任务, 有返回。将结果返回, 外部可以获取到值CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {@Overridepublic String get() {System.out.println("我是一个内部有返回的方法");return "我是返回值";}});// 调用此方法, 完成上面的异步执行。如果不调用, 则不会显示结果String content = future.get();System.out.println(content);}
}

运行结果

我是一个内部有返回的方法
我是返回值




第二章 获取结果

第01节 同步获取结果

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 异步执行任务CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {@Overridepublic String get() {System.out.println("我是一个内部有返回的方法");try {TimeUnit.SECONDS.sleep(5);return "正常情况";} catch (InterruptedException e) {return "异常值";}}});String content = future.get();System.out.println("正常 content = " + content);}
}

运行结果

我是一个内部有返回的方法
正常 content = 正常情况




第02节 超时获取结果

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 异步执行任务CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {@Overridepublic String get() {System.out.println("我是一个内部有返回的方法");try {TimeUnit.SECONDS.sleep(5);return "正常情况";} catch (InterruptedException e) {return "异常值";}}});String content = null;try {content = future.get(3, TimeUnit.SECONDS);System.out.println("正常 content = " + content);}catch (TimeoutException timeoutException){System.out.println("超时 content = " + content);}}
}// 说明: 
// 1、在 future 内部定义了 5秒的延迟, 我们设置的超时时间是 3秒, 如果 3秒未获取到结果, 那么直接显示 超时
// 2、在 future 内部定义了 5秒的延迟, 如果 我们设置的超时时间是 5秒, 如果 5秒未获取到结果, 那么直接显示 超时 (两个时间相等时, 也是超时)
// 3、在 future 内部定义了 5秒的延迟, 如果 我们设置的超时时间是 6秒, 如果 5秒未获取到结果, 那么直接显示 正常 (大于延迟时间, 显示正常)

运行结果

我是一个内部有返回的方法
超时 content = null




第03节 获取默认结果

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 异步执行任务CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {@Overridepublic String get() {System.out.println("我是一个内部有返回的方法");return "正常情况";}});String content = future.getNow("默认值");System.out.println("content = " + content);}
}// 直接返回的是默认值, 不管里面的内容是否正常

运行结果

我是一个内部有返回的方法
content = 默认值




第04节 两类获取值操作

案例代码

public class Demo {public static void main(String[] args) {// 异步执行任务 有返回值 自定义线程CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {@Overridepublic String get() {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}return "正常值";}});// 采用Get 的方式获取数据值, 需要处理异常(可以解决超时的问题)try {String contentGet = future.get(2, TimeUnit.SECONDS);System.out.println("contentGet = " + contentGet);} catch (Exception exception) {System.out.println("出现异常的情况." + exception);}// 采用Join 的方式获取数据值, 无需处理异常(不能解决超时的问题)String contentJoin = future.join();System.out.println("contentJoin = " + contentJoin);}
}// 对比 Join 和 Get 两个方法
// 1、Get 方法需要处理异常, 可以定义超时时间, 在异常中关注 TimeOutException 可以处理超时的问题
// 2、Join 方法无需处理异常, 不可以定义超时时间, 可以用于 stream 流操作更方便。

运行结果

出现异常的情况.java.util.concurrent.TimeoutException
contentJoin = 正常值




第三章 自定义线程池操作

第01节 异步任务 无返回值 自定义线程池

案例代码


public class Demo {public static void main(String[] args) throws Exception {// 异步执行任务 无返回值 自定义线程// 定义线程池ExecutorService executor = Executors.newFixedThreadPool(4);CompletableFuture<Void> future = CompletableFuture.runAsync(new Runnable() {@Overridepublic void run() {System.out.println("我是一个内部无返回的方法: " + Thread.currentThread().getName());}}, executor);future.get();// 关闭线程池executor.shutdown();}
}

运行结果

我是一个内部无返回的方法: pool-1-thread-1




第02节 异步任务 有返回值 自定义线程池

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 异步执行任务 有返回值 自定义线程// 定义线程池ExecutorService executor = Executors.newFixedThreadPool(4);CompletableFuture<String> future = CompletableFuture.supplyAsync(new Supplier<String>() {@Overridepublic String get() {System.out.println("我是一个内部有返回的方法: " + Thread.currentThread().getName());return "正常情况";}}, executor);String content = future.get();System.out.println("content = " + content);// 关闭线程池executor.shutdown();}
}

运行结果

我是一个内部有返回的方法: pool-1-thread-1
content = 正常情况




第四章 组合多个CompletableFuture

第01节 串联组合 thenCompose

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 顺序组合 thenCompose// 将 第01个CompletableFuture 的结果 str 与 第02个CompletableFuture 组合在一起CompletableFuture<String> future =CompletableFuture.supplyAsync(() -> {return "第01个CompletableFuture";}).thenCompose(str ->CompletableFuture.supplyAsync(() -> {return str.concat("第02个CompletableFuture");}));String content = future.get();System.out.println("结果: " + content);}
}// 类似于 物理电路图的 串联方式

运行结果

结果: 第01个CompletableFuture第02个CompletableFuture

效果图

在这里插入图片描述




第02节 并联组合 thenCombine

案例代码

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;public class Demo {public static void main(String[] args) throws Exception {// 并行组合 thenCombine// 将 第01个CompletableFuture 的结果  与 第02个CompletableFuture 收集存储在一起CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {return "第01个CompletableFuture";});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {return "第02个CompletableFuture";});CompletableFuture<List<String>> future = future1.thenCombine(future2, new BiFunction<String, String, List<String>>() {@Overridepublic List<String> apply(String s1, String s2) {List<String> list = new ArrayList<>();list.add(s1);list.add(s2);return list;}});List<String> content = future.get();System.out.println("结果: " + content);}
}// 类似于 物理电路图的 并联方式

运行结果

结果: [第01个CompletableFuture, 第02个CompletableFuture]

效果图

在这里插入图片描述




第03节 多任务全部完成 allOf

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 组合 allOf 等待所有的 CompletableFuture 完成之后, 给出通知CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("第01个CompletableFuture 完成");return "第01个CompletableFuture";});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("第02个CompletableFuture 完成");return "第02个CompletableFuture";});CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("第03个CompletableFuture 完成");return "第03个CompletableFuture";});// 组合所有的 futureCompletableFuture<Void> futureAll = CompletableFuture.allOf(future1, future2, future3);// 通知全部已经完成了CompletableFuture<Object> future = futureAll.thenApply(unused -> "所有的future都完成了");Object content = future.get();System.out.println("结果: " + content);}
}

运行结果

第01个CompletableFuture 完成
第02个CompletableFuture 完成
第03个CompletableFuture 完成
结果: 所有的future都完成了

效果图

在这里插入图片描述




第04节 多个任务任一完成 anyOf

代码

public class Demo {public static void main(String[] args) throws Exception {// 组合 anyOf 其中任何一个 future 完成就给通知CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("第01个CompletableFuture 完成");return "第01个CompletableFuture";});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("第02个CompletableFuture 完成");return "第02个CompletableFuture";});CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {try {TimeUnit.SECONDS.sleep(3);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("第03个CompletableFuture 完成");return "第03个CompletableFuture";});// 并行完成多个 futureCompletableFuture<Object> futureAll = CompletableFuture.anyOf(future1, future2, future3);// 其中任何一个 future 完成就给通知CompletableFuture<Object> future = futureAll.thenApply(unused -> "有某个future完成了");Object content = future.get();System.out.println("结果: " + content);}
}

运行结果

第01个CompletableFuture 完成
结果: 有某个future完成了

效果图

在这里插入图片描述




第五章 链式调用

第01节 链式转换 thenApply

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 转换 thenApply 将前一个 CompletableFuture 的值 转换成为另一个值类型CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {System.out.println("第01个CompletableFuture 完成");return "ABCDEFGabcdefg";}).thenApply(new Function<String, String>() {@Overridepublic String apply(String element) {System.out.println("第02个CompletableFuture 完成: " + element);return element.toUpperCase();}}).thenApply(new Function<String, Integer>() {@Overridepublic Integer apply(String element) {System.out.println("第03个CompletableFuture 完成: " + element);return element.length();}});// 显示最终的结果int content = future.get();System.out.println("结果: " + content);}
}

运行结果

第01个CompletableFuture 完成
第02个CompletableFuture 完成: ABCDEFGabcdefg
第03个CompletableFuture 完成: ABCDEFGABCDEFG
结果: 14




第02节 终结链路 thenAccept

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 终结链路 thenAcceptCompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {System.out.println("第01个CompletableFuture 完成");return "ABCDEFGabcdefg";}).thenApply(new Function<String, String>() {@Overridepublic String apply(String element) {System.out.println("第02个CompletableFuture 完成: " + element);return element.toUpperCase();}}).thenApply(new Function<String, Integer>() {@Overridepublic Integer apply(String element) {System.out.println("第03个CompletableFuture 完成: " + element);return element.length();}});// 显示最终的结果, 终结链路。 thenAccept 将结果消费掉 Consumerfuture.thenAccept(new Consumer<Integer>() {@Overridepublic void accept(Integer count) {System.out.println("结果: " + count);}});}
}

运行结果

第01个CompletableFuture 完成
第02个CompletableFuture 完成: ABCDEFGabcdefg
第03个CompletableFuture 完成: ABCDEFGABCDEFG
结果: 14




第六章 异常处理

第01节 保留前面任务 exceptionally

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 异常处理, 保留前面任务 操作 exceptionallyCompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {System.out.println("第01个任务");return "result1";}).thenApply(s -> {int x = 3/0;        // 这里出现异常System.out.println("第02个任务");return s + "-result2";}).thenApply(s -> {System.out.println("第03个任务");// 第三个return s + "-result3";}).exceptionally(throwable -> {System.out.println("异常: " + throwable);return "UnKnow";});String content = future.get();System.out.println("结果: " + content);}
}

运行结果

第01个任务
异常: java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
结果: UnKnow




第02节 保留后面任务 handle

案例代码

public class Demo {public static void main(String[] args) throws Exception {// 异常处理, 保留后面任务 操作 handleCompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {System.out.println("第01个任务");return "result1";}).handle(new BiFunction<String, Throwable, String>() {@Overridepublic String apply(String result, Throwable throwable) {if (throwable != null) {System.out.println("第01个任务, 出现异常: " + throwable);return "UnKnow";}return result;}}).thenApply(s -> {int x = 3 / 0;        // 这里出现异常System.out.println("第02个任务");return s + "-result2";}).handle(new BiFunction<String, Throwable, String>() {@Overridepublic String apply(String result, Throwable throwable) {if (throwable != null) {System.out.println("第02个任务, 出现异常: " + throwable);return "UnKnow";}return result;}}).thenApply(s -> {System.out.println("第03个任务");// 第三个return s + "-result3";}).handle(new BiFunction<String, Throwable, String>() {@Overridepublic String apply(String result, Throwable throwable) {if (throwable != null) {System.out.println("第03个任务, 出现异常: " + throwable);return "UnKnow";}return result;}});String content = future.get();System.out.println("结果: " + content);}
}

运行结果

第01个任务
第02个任务, 出现异常: java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero
第03个任务
结果: UnKnow-result3




http://www.dtcms.com/a/318905.html

相关文章:

  • 技术优势铸就行业标杆:物联网边缘计算网关凭何引领智能变革?
  • 施耐德 Easy Altivar ATV310 变频器:高效电机控制的理想选择(含快速调试步骤及常见故障代码)
  • Flutter 局部刷新方案对比:ValueListenableBuilder vs. GetBuilder vs. Obx
  • 齐护机器人小智AI_MCP图形化编程控制Arduino_ESP32
  • 亚远景-ISO 42001:汽车AI安全的行业标准新趋势
  • 网站 博客遭遇DDoS,CC攻击应该怎样应对?
  • crew AI笔记[2] - 如何选型
  • MCU-TC397的UCB初识
  • 初识 MQ:从同步到异步,聊聊消息队列那些事
  • OpenCv对图片视频的简单操作
  • 深度学习(2):自动微分
  • 学深度学习,有什么好的建议或推荐的书籍?
  • MobileNetV3: 高效移动端深度学习的前沿实现
  • 从“炼金术”到“工程学”:深度学习十年范式变迁与未来十年路线图
  • 深度学习之opencv篇
  • HashMap寻址算法
  • QT项目 -仿QQ音乐的音乐播放器(第五节)
  • 《算法导论》第 10 章 - 基本数据结构
  • 深入剖析Java线程:从基础到实战(上)
  • ubuntu cloud init 20.04LTS升级到22.04LTS
  • vue3接收SSE流数据进行实时渲染日志
  • Web开发模式 前端渲染 后端渲染 身份认证
  • 第三章:【springboot】框架介绍MyBatis
  • Spring AOP动态代理核心原理深度解析 - 图解+实战揭秘Java代理设计模式
  • 前端百分比展示导致后端 BigDecimal 转换异常的排查与解决
  • 多账号管理方案:解析一款免Root的App分身工具
  • 【RabbitMQ面试精讲 Day 13】HAProxy与负载均衡配置
  • HTTP 协议升级(HTTP Upgrade)机制
  • winform中的listbox实现拖拽功能
  • 基于ubuntu搭建gitlab