函数编程实际应用-异步任务

embedded/2024/9/25 8:03:01/

背景

  • 常见的函数式接口,就是对函数编程的应用
  • Runnable 没有返回值的函数式接口
  • Callable 有返回值的函数式接口

使用线程池

  • 一般来说,很少使用new Thread(函数对象)这种方式来直接 创建线程,更多的时候使用的线程成来集中管理线程,避免频繁开关线程造成的资源浪费
  • 线程池对象的调用使用submit 方法,传入一个函数对象,可以使callable的,也可以是runnable的
  • 如果有返回值,返回值使用Future来接受,同时返回类型和Future的泛型保持一致
  • 调用线程方法get之后,会开辟新的线程继续执行,但是主线程会一直阻塞等待线程的返回结果
    在这里插入图片描述
java">ExecutorService executorService = Executors.newFixedThreadPool(3);
Future<String> thread = executorService.submit(() -> {System.out.println("线程1开始执行");Thread.sleep(5000);System.out.println("线程1执行完毕");return "success1";
});
Future<String> thread2 = executorService.submit(() -> {System.out.println("线程2开始执行");Thread.sleep(10000);System.out.println("线程2执行完毕");return "success2";
});
try {// 这种形式会将线程进行阻塞,等到两个线程执行完毕后才会继续执行System.out.println("主线程开始执行");String s = thread.get();System.out.println("线程执行中");String s1 = thread2.get();System.out.println("线程执行完毕"+s+s1);System.out.println("主线程执行完毕");
} catch (InterruptedException e) {throw new RuntimeException(e);
} catch (ExecutionException e) {throw new RuntimeException(e);
}

上述方案的缺点

  • 显式的使用线程池,一般程序员对于线程池的使用并不熟练
  • 使用匿名函数的方式书写方法体,如果后续的方法体逻辑复杂的话,可能有很多嵌套,代码的可读性将会变得很差
  • 解决方案:使用1.8引入的 CompletableFuture
  • 这个解决方案的优点,你可以将 数据的处理过程进行拆分,同时将上一步的结果返回给下一步进行处理,这种方式类似于前端的then ,这种解决方式类似于前端解决回调地狱的操作

同步消费 结果

  • thenAccept 将得到的结果同步消费
java">        CompletableFuture<String> stringCompletableFuture1 = CompletableFuture.supplyAsync(() -> {System.out.println("异步任务1开始");try {Thread.sleep(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("异步任务1结束");return "异步任务1";});CompletableFuture<String> stringCompletableFuture2 = CompletableFuture.supplyAsync(() -> {System.out.println("异步任务2开始");try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("异步任务2结束");return "异步任务2";});// 将得到的两个线程的任务 直接同步执行stringCompletableFuture1.thenAccept(System.out::println);stringCompletableFuture2.thenAccept(System.out::println);System.in.read();// 阻塞主线程 主线程不要那么早结束

异步消费 结果

得到结果之后,将结果丢给一个consumer,开启一个新的线程来消费这个结果

java">        CompletableFuture<String> stringCompletableFuture1 = CompletableFuture.supplyAsync(() -> {System.out.println("异步任务1开始");try {Thread.sleep(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("异步任务1结束");return "异步任务1";});CompletableFuture<String> stringCompletableFuture2 = CompletableFuture.supplyAsync(() -> {System.out.println("异步任务2开始");try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("异步任务2结束");return "异步任务2";});// 将得到的两个线程的任务 异步执行stringCompletableFuture1.thenAcceptAsync(r -> {try {Thread.sleep(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(r);System.out.println("异步任务1的结果消费完毕");});stringCompletableFuture2.thenAcceptAsync(r -> {try {Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(r);System.out.println("异步任务2的结果消费完毕");});System.in.read();// 阻塞主线程 主线程不要那么早结束

异步转换数据

  • 一般来说thenApplyAsync 转换之后,得到的还是一个CompletableFuture,一般再转换之后还是需要一个Consumer进行消费
java"> // 异步转换  再将转换后的结果同步消费stringCompletableFuture1.thenApplyAsync(r -> {try {Thread.sleep(10000);} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(r);System.out.println("异步任务1的结果消费完毕");return r + "转换";}).thenAccept(System.out::println);

http://www.ppmy.cn/embedded/44198.html

相关文章

计算机网络基本概念

文章目录 情景带入一些基本概念网络网络编程&#xff1a;7层网络模型OSI&#xff1a;TCP/IP Protocol Architecture Layers与OSI的对应关系SocketClient-Server Application报文段&#xff1a;传输协议&#xff1a;Mac地址IP地址端口URL 情景带入 随着时代的发展&#xff0c;我…

永久代(Permanent Generation)和元空间(Metaspace)

永久代&#xff08;Permanent Generation&#xff09;和元空间&#xff08;Metaspace&#xff09;是Java虚拟机&#xff08;JVM&#xff09;内存管理中的两个概念&#xff0c;主要区别在于它们的实现方式和内存分配策略。 永久代&#xff08;Permanent Generation&#xff09;…

使用 Supabase 的 Realtime + Storage 非常方便呢

文章目录 &#xff08;一&#xff09;Supabase&#xff08;二&#xff09;Realtime&#xff08;消息&#xff09;&#xff08;2.1&#xff09;Python 消息订阅&#xff08;2.2&#xff09;JavaScript 消息订阅 &#xff08;三&#xff09;Storage&#xff08;存储&#xff09;&…

python规则表达式re模块:笔记0529

Python语言使用printf printf&#xff1a;https://blog.51cto.com/u_16099181/7758801 使用python进行自动化运维脚本编写时经常需要处理远程设备返回到控制字符&#xff0c;比如下面这个例子&#xff0c;控制字符在使用print进行调试输出时因为是非ascii字符不显示&#xff0…

Vue插槽solt如何传递具名插槽的数据给子组件?

在Vue中&#xff0c;你可以通过作用域插槽&#xff08;scoped slots&#xff09;来传递数据给子组件。这同样适用于具名插槽。首先&#xff0c;你需要在子组件中定义一个具名插槽&#xff0c;并通过v-slot指令传递数据。例如&#xff1a; 子组件&#xff08;ChildComponent.vu…

长安链使用Golang编写智能合约教程(二)

长安链2.3.0的go合约虚拟机和2.3.0以下的不兼容&#xff0c;编译的方式也有差异&#xff0c;所以在ide上做了区分。 教程三会写一些&#xff0c;其他比较常用SDK方法的解释和使用方法 教程一&#xff1a;&#xff08;长安链2.1.的版本的智能合约&#xff09; 教程三&#xff…

C#【进阶】特殊语法

特殊语法、值和引用类型 特殊语法 文章目录 特殊语法1、var隐式类型2、设置对象初始值3、设置集合初始值4、匿名类型5、可空类型6、空合并操作符7、内插字符串8、单句逻辑简略写法 值和引用类型1、判断值和引用类型2、语句块3、变量的生命周期4、结构体中的值和引用5、类中的值…

类似笔趣阁的免费软件有什么?看小说app哪个最好最全?试试这些任何小说都能看的软件

笔趣阁哪个才是正版&#xff1f;相信很多人想知道答案。 今天阿星跟大家聊聊那些能免费读小说、看全网漫画的app&#xff0c;低调推荐&#xff0c;希望让你告别书荒&#xff01; 追书大全 首先登场的是“追书大全”这款APP&#xff0c;简直是小说迷的天堂&#xff01; 在这…