Java8 CompletableFuture runAsync等使用学习总结 submit() execute()等

article/2025/10/28 7:18:59

一般的 Executors 的 execute以及submit

并发包下 Executors 创建的线程存在 一个 execute(),以及三个 submit()
不同的是使用 execute() 执行的任务是没有返回值的,使用 submit() 则是存在返回值的,这与接下里要说的 CompletableFuture.runAsync 有些类似。
在这里插入图片描述
在这里插入图片描述
中测试代码如下:

    @Testpublic void justFor(){ExecutorService executorService = Executors.newSingleThreadExecutor();Future<Float> submit = executorService.submit(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 1.03f;});Float aFloat = null;try {aFloat = submit.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}// 根据自己需要决定是否需要调用关闭线程
//        executorService.shutdown();System.out.println("aFloat = " + aFloat);}

结果:

Thread.currentThread() = Thread[pool-2-thread-1,5,main]
aFloat = 1.03

使用 submit 可以通过 get获取线程中任务的返回结果,可以通过对象获取当前状态 isDone 或者 isCancelled ;

子线程异步执行,主线程休眠等待子线程执行完成,子线程执行完成后唤醒主线程,主线程获取任务执行结果后退出
此时我加入一个异常代码,使其必定出错再来看看结果

    @Testpublic void justFor(){ExecutorService executorService = Executors.newSingleThreadExecutor();Future<Float> submit = executorService.submit(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());int ii = 1/0;return 1.2f;});Float aFloat = null;try {aFloat = submit.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}
//        executorService.shutdown();System.out.println("aFloat = " + aFloat);}

执行结果:
在这里插入图片描述
此时即使异常依旧终止了子线程以及主线程的执行。

CompletableFuture 的 supplyAsync() / runAsync()

supplyAsync 表示创建带返回值的异步任务,相当于ExecutorService submit(Callable< T> task)
runAsync 表示创建无返回值的异步任务,相当于ExecutorService submit(Runnable task)方法,这两个方法效果与 submit 一致
示例代码:

    @Testpublic void justFor(){CompletableFuture<Float> floatCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 1.03f;});try {Float aFloat = floatCompletableFuture.get();System.out.println("Thread.currentThread() = " + Thread.currentThread());System.out.println("aFloat = " + aFloat);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}

输出结果:

Thread.currentThread() = Thread[ForkJoinPool.commonPool-worker-1,5,main]
Thread.currentThread() = Thread[main,5,main]
aFloat = 1.03

日志中 ForkJoinPool 为jdk1.7 提供的一个新的分而治之的性能更好的并发处理线程池,比一般的Executors 更好一点,适用于高密度计算的任务。

但也可以如此写
在这里插入图片描述
即将该任务提交到指定的线程池中执行该任务;
输出的线程池不一致

类似的 runAsync() 也可以这样,使用自己的异步线程或者提交到指定的线程池中执行
在这里插入图片描述

可以看得出使用第二个参数均提供了可以指定 Executor 没有指定时默认使用 ForkJoinPool.commonPool()

一般的
runAsync 如下:

CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return;});

可以看得出 并没有任何返回值

CompletableFuture 的 thenApply() / thenApplyAsync()

在这里插入图片描述

thenApply 表示某个任务执行完成后执行的动作即回调方法,会将该任务的执行结果即方法的返回值会作为作为入参传递到接下来的回调方法中
示例代码:

    @Testpublic void justFor(){CompletableFuture<Float> floatCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 1.03f;});CompletableFuture<Float> floatCompletableFuture1 = floatCompletableFuture.thenApply((resultFloat) -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());System.out.println("接受上一个 resultFloat = " + resultFloat);return 2.01f;});CompletableFuture<Float> floatCompletableFuture2 = floatCompletableFuture1.thenApplyAsync((result2) -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());System.out.println("result2 = " + result2);return 2.21f;});try {Float aFloat = floatCompletableFuture.get();System.out.println("Thread.currentThread() = " + Thread.currentThread());System.out.println("aFloat = " + aFloat);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}

输出结果:

Thread.currentThread() = Thread[ForkJoinPool.commonPool-worker-1,5,main]
Thread.currentThread() = Thread[main,5,main]
接受上一个 resultFloat = 1.03
Thread.currentThread() = Thread[main,5,main]
Thread.currentThread() = Thread[ForkJoinPool.commonPool-worker-1,5,main]
aFloat = 1.03
result2 = 2.01

thenApplyAsyncthenApply 区别:
thenApplyAsync 将任务异步处理,可以选择提交到某一个线程池中执行,thenApply 则将会在上一个任务的同一个线程中执行。

上面代码也可以连着书写如下:
在这里插入图片描述

CompletableFuture 的 thenAccept() / thenRun()

thenAcceptthenApply 接收上一个任务的返回值作为参数但是没有返回值
thenAcceptAsync 同上但为异步线程,可以指定提交到某一个线程池中
thenRun 方法没有入参,也没有返回值
thenRunAsync 同上但为异步线程,可以指定提交到某一个线程池中
示例代码:

    @Testpublic void justFor(){CompletableFuture<Float> floatCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 1.03f;});CompletableFuture<Void> floatCompletableFuture1= floatCompletableFuture.thenApply((resultFloat) -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());System.out.println("接受上一个 resultFloat = " + resultFloat);return 2.01f;}).thenAccept((result)->{System.out.println("Thread.currentThread() = " + Thread.currentThread());System.out.println("result = " + result);}).thenRun(()->{System.out.println("Thread.currentThread() = " + Thread.currentThread());System.out.println(" doNothing");});}

CompletableFuture exceptionally

指定某个任务执行异常时执行的回调方法,会将抛出异常作为参数传递到回调方法中,如果该任务正常执行则 exceptionally方法返回的CompletionStage的result就是该任务正常执行的结果
正常示例:

    @Testpublic void justFor(){CompletableFuture<Float> floatCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());
//            float ii = 1/0;return 1.03f;});CompletableFuture<Float> exceptionally = floatCompletableFuture.exceptionally((exception) -> {System.out.println("catch exception");exception.printStackTrace();return 0.0f;});floatCompletableFuture.thenAccept((result)->{System.out.println("is OK");System.out.println("result = " + result);});}

输出结果:

Thread.currentThread() = Thread[ForkJoinPool.commonPool-worker-1,5,main]
is OK

异常示例:

    @Testpublic void justFor(){CompletableFuture<Float> floatCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());int a = 121/0;return 1.03f;});CompletableFuture<Float> exceptionally = floatCompletableFuture.exceptionally((exception) -> {System.out.println("catch exception");exception.printStackTrace();return 0.0f;});floatCompletableFuture.thenAccept((result)->{System.out.println("is OK");System.out.println("result = " + result);});}

结果:

Thread.currentThread() = Thread[ForkJoinPool.commonPool-worker-1,5,main]
catch exception

CompletableFuture whenComplete

当某个任务执行完成后执行的回调方法,会将执行结果或者执行期间抛出的异常传递给回调方法

正常执行则异常为null,回调方法对应的CompletableFuture的result和该任务一致
异常执行,则get方法抛出异常
同样提供 Async 异步相关方法

正常:

    @Testpublic void justFor(){CompletableFuture<Float> floatCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 1.03f;});floatCompletableFuture.whenComplete((result, exception) -> {System.out.println("result = " + result);System.out.println("exception = " + exception);});}

输出:

Thread.currentThread() = Thread[ForkJoinPool.commonPool-worker-1,5,main]
result = 1.03
exception = null

异常时示例:

    public static void main(String[] args) {CompletableFuture<Float> floatCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());int ii = 12 / 0;return 1.03f;});floatCompletableFuture.whenComplete((result, exception) -> {System.out.println("result = " + result);System.out.println("exception = " + exception);});}

输出:

Thread.currentThread() = Thread[ForkJoinPool.commonPool-worker-1,5,main]
result = null
exception = java.util.concurrent.CompletionException: java.lang.ArithmeticException: / by zero

CompletableFuture handle

whenComplete 基本一致
区别在于handle的回调方法有返回值,且handle方法返回的CompletableFuture的result是回调方法的执行结果或者回调方法执行期间抛出的异常,与原始CompletableFuture的result无关
示例代码:

    @Testpublic void justFor(){CompletableFuture<Float> floatCompletableFuture = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());int ii = 12 / 0;return 1.03f;});floatCompletableFuture.handle((result, exception) -> {System.out.println("result = " + result);System.out.println("exception = " + exception);return "???";});}

CompletableFuture 组合处理 thenCombine / thenAcceptBoth / runAfterBoth

三个方法都是将两个 CompletableFuture 组合起来
只有这两个都正常执行完了才会执行某个任务区别在于
thenCombine 会将两个任务的执行结果作为方法入参传递到指定方法中,且该方法有返回值;thenAcceptBoth 同样将两个任务的执行结果作为方法入参,但是无返回值;
runAfterBoth 没有入参,也没有返回值。注意两个任务中只要有一个执行异常,则将该异常信息作为指定任务的执行结果

同时这些也提供了Async 异步方法
示例代码:

    @Testpublic void justFor(){CompletableFuture<Float> a1 = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 1.03f;});CompletableFuture<Float> a2 = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 2.03f;});// 传递结果 有返回值CompletableFuture<String> objectCompletableFuture = a1.thenCombine(a2, (a, b) -> {return "12";});// 传递结果  无返回值CompletableFuture<Void> voidCompletableFuture = a1.thenAcceptBoth(a2, (a, b) -> {});// 无入参 无返回值a1.runAfterBoth(a2, ()->{//});}

CompletableFuture applyToEither / acceptEither / runAfterEither

三个方法都是将两个CompletableFuture组合起来
但与上面不同的是只要其中一个执行完了就会执行某个任务,区别
applyToEither 会将已经执行完成的任务的执行结果作为方法入参,并有返回值;
acceptEither 同样将已经执行完成的任务的执行结果作为方法入参,但是没有返回值;runAfterEither 没有方法入参,也没有返回值。
注意 两个任务中只要有一个执行异常,则将该异常信息作为指定任务的执行结果

同时这些也提供了Async 异步方法
示例代码:

    @Testpublic void justFor(){CompletableFuture<Float> a1 = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 1.03f;});CompletableFuture<Float> a2 = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 2.03f;});// 传递结果 有返回值CompletableFuture<String> objectCompletableFuture = a1.applyToEither(a2, (b) -> {return "12";});// 传递结果  无返回值CompletableFuture<Void> voidCompletableFuture = a1.acceptEither(a2, (b) -> {});// 无入参 无返回值a1.runAfterEither(a2, ()->{//});}

CompletableFuture thenCompose

thenCompose
在某个任务执行完成后,将该任务的执行结果作为方法入参然后执行指定方法,该方法会返回一个新的CompletableFuture实例
如果该CompletableFuture实例的result不为null,则返回一个基于该result的新的CompletableFuture实例;
如果该CompletableFuture实例为null,则执行这个新任务

同样的提供Async方式

    @Testpublic void justFor(){CompletableFuture<Float> a1 = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 1.03f;});CompletableFuture<String> stringCompletableFuture = a1.thenCompose((result) -> {System.out.println("result = " + result);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}return CompletableFuture.supplyAsync(() -> {return "154";});});}

CompletableFuture 的 allOf() anyOf()

allOf 返回的CompletableFuture是多个任务都执行完成后才会执行,只要有一个任务执行异常,则返回的 CompletableFuture 执行get方法时会抛出异常,如果都正常执行,则get返回null

anyOf 只要有一个任务执行完成,无论是正常执行或者执行异常,都会执行向下执行

示例代码:

    @Testpublic void justFor(){CompletableFuture<Float> a1 = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 1.03f;});CompletableFuture<Float> a2 = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 2.03f;});CompletableFuture<Float> a3 = CompletableFuture.supplyAsync(() -> {System.out.println("Thread.currentThread() = " + Thread.currentThread());return 23.03f;});CompletableFuture.allOf(a1, a2, a3).whenComplete((a, b)->{System.out.println("a = " + a);System.out.println("b = " + b);});CompletableFuture<Object> objectCompletableFuture = CompletableFuture.anyOf(a1, a2, a3);try {Object o = objectCompletableFuture.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}

http://chatgpt.dhexx.cn/article/r7nvHhtk.shtml

相关文章

实现异步编程,这个工具类你得掌握!

前言 最近看公司代码&#xff0c;多线程编程用的比较多&#xff0c;其中有对CompletableFuture的使用&#xff0c;所以想写篇文章总结下 在日常的Java8项目开发中&#xff0c;CompletableFuture是很强大的并行开发工具&#xff0c;其语法贴近java8的语法风格&#xff0c;与st…

Java异步编程之CompletableFuture

异步任务 Future获取异步任务结果 利用 Java 并发包提供的 Future 可以很容易获得异步任务的执行结果&#xff0c;无论异步任务是通过线程池 ThreadPoolExecutor 执行的&#xff0c;还是通过手工创建子线程来执行的。利用多线程可以快速将一些串行的任务并行化&#xff0c;从而…

JUC异步编程

什么是JUC JUC的意思是java并发编程工具包&#xff0c;是java.util.concurrent包的简称。目的就是为了更好的支持高并发任务&#xff0c;让开发者利用这个包进行的多线程开发时&#xff0c;可以有效的减少竞争条件和死锁线程。 异步编程 模拟用户下单操作。。。 1、根据地址…

线程、多线程的使用、线程池、异步(CompletableFuture)-48

一&#xff1a;线程 1.初始化线程的四种方式 1&#xff09;、继承 Thread public class ThreadTest {public static void main(String[] args) {System.out.println("main...start...");Thread01 thread new Thread01();//启动线程thread.start();System.out.pri…

CompletableFuture 执行异步任务

CompletableFuture 执行异步任务 参考&#xff1a; (10条消息) Java 8 的异步编程利器 CompletableFuture 真香&#xff01;_不才陈某的博客-CSDN博客 提供几十种方法&#xff0c;帮助异步任务执行调用&#xff1b; 主要包括&#xff1a; 创建异步任务任务异步回调多个任务…

CompletableFuture实现异步编排全面分析和总结

一、&#x1f308;CompletableFuture简介 CompletableFuture结合了Future的优点&#xff0c;提供了非常强大的Future的扩展功能&#xff0c;可以帮助我们简化异步编程的复杂性&#xff0c;提供了函数式编程的能力&#xff0c;可以通过回调的方式处理计算结果&#xff0c;并且提…

【Java8新特性--->异步处理】CompletableFuture

一、引入 假设一个商品详情页需要以下操作&#xff1a; 查询展示商品的基本信息耗时&#xff1a;0.5s查询展示商品的销售信息耗时&#xff1a;0.7s查询展示商品的图片信息耗时&#xff1a;1s查询展示商品销售属性耗时&#xff1a;0.3s查询展示商品规格属性耗时&#xff1a;1.…

CompletableFuture API

目录 1. 为什么要用CompletableFuture1.1 API 2. CompletableFuture Demo1. 创建CompletableFuture2. 定义CompletableFuture完成时和异常时需要回调的实例3. CompletableFuture的优点 3. demo&#xff1a;多个CompletableFuture串行执行4. demo&#xff1a;多个CompletableFut…

CompletableFuture实战与分析

Future对于结果的获取不够好&#xff0c;只能通过阻塞或者轮询的方式得到任务的结果。在Java8中Doug Lea大师提供了一个CompletableFuture工具类&#xff0c;可以更优雅的对异步并行操作进行编排。 Future VS CompletableFuture CompletableFuture支持手动完成任务&#xff0…

Java8 CompletableFuture异步非阻塞做法

创建异步任务 Future.submit supplyAsync / runAsync 异步回调 thenApply / thenApplyAsync thenAccept / thenRun exceptionally whenComplete handle 组合处理 thenCombine / thenAcceptBoth / runAfterBoth applyToEither / acceptEither / runAfterEither thenCom…

2022.2.5 第十三次周报

文章目录 前言一、论文阅读《ROCKET: Exceptionally fast and accurate time series classification using random convolutional kernels》Abstract摘要Introduction介绍Method方法Kernels内核Transform转换Classifier分类器Complexity Analysis复杂性分析 Experiments实验Con…

并发编程(十五)-CompletableFuture中常用方法的使用与分析

文章目录 一、CompletableFuture API介绍1. 描述2. CompletionStage3. CompletableFuture 4个核心静态方法&#xff08;1&#xff09;runAsync(Runnable runnable)&#xff08;2&#xff09;runAsync(Runnable runnable, Executor executor)&#xff08;3&#xff09;supplyAsy…

Java 编程问题:十一、并发-深入探索

原文&#xff1a;Java Coding Problems 协议&#xff1a;CC BY-NC-SA 4.0 贡献者&#xff1a;飞龙 本文来自【ApacheCN Java 译文集】&#xff0c;自豪地采用谷歌翻译。 本章包括涉及 Java 并发的 13 个问题&#xff0c;涉及 Fork/Join 框架、CompletableFuture、ReentrantLock…

线程(十二)---CompletableFuture(三)

写在前面&#xff1a;各位看到此博客的小伙伴&#xff0c;如有不对的地方请及时通过私信我或者评论此博客的方式指出&#xff0c;以免误人子弟。多谢&#xff01; 示例五&#xff1a;异常处理 接着上一篇记录一下CompletableFuture的异常处理&#xff0c;异常处理通常使用…

dice loss

Dice Loss 最先是在VNet 这篇文章中被提出&#xff0c;后来被广泛的应用在了医学影像分割之中。 Dice 系数 Dice系数作为损失函数的原因和混淆矩阵有着很大的关系&#xff0c;下图给出的是一个混淆矩阵&#xff1a; 其中的一些关键指标如下&#xff1a; 精确率(precision)表…

Hinge loss

声明&#xff1a; 参考自维基百科后面可能会更新 Hinge Loss 在机器学习中&#xff0c;hinge loss作为一个损失函数(loss function)&#xff0c;通常被用于最大间隔算法(maximum-margin)&#xff0c;而最大间隔算法又是SVM(支持向量机support vector machines)用到的重要算法…

【深度学习】一文读懂机器学习常用损失函数(Loss Function)

【深度学习】一文读懂机器学习常用损失函数&#xff08;Loss Function&#xff09; 最近太忙已经好久没有写博客了&#xff0c;今天整理分享一篇关于损失函数的文章吧&#xff0c;以前对损失函数的理解不够深入&#xff0c;没有真正理解每个损失函数的特点以及应用范围&#x…

Pytorch之loss(损失函数)

损失函数也在torch.nn下&#xff0c;具体可以参考文档&#xff0c;也可以参考官网 先根据L1Loss举例 我个人感觉这里的描述还是到官网的文档找比较好&#xff0c;公式看的比文档清楚 import torch from torch import nninputs torch.tensor([[3, 2, 1],[1, 2, 3]], dtypetorch…

机器学习 损失函数 Loss function

损失函数 最小二乘法极大似然估计法交叉熵 【本文根据B站-王木头学科学-视频所学】 在梯度下降中&#xff0c;所求的梯度其实就是损失函数的梯度。 损失函数有三种设计方法&#xff1a; &#xff08;1&#xff09;最小二乘法 &#xff08;2&#xff09;极大似然估计法 &#x…

Focal loss 损失函数详解

Focal loss 目前目标检测的算法大致分为两类&#xff0c;One Stage 、Two Stage。 One Stage&#xff1a;主要指类似YOLO、SGD等这样不需要region proposal,直接回归的检测算法&#xff0c;这类算法检测速度很快&#xff0c;但是精度准确率不如使用Two stage的模型。 two St…