关于 CompletableFuture 类的疑惑 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
7911364440
V2EX    Java

关于 CompletableFuture 类的疑惑

  •  
  •   7911364440 2022 年 8 月 4 日 2762 次点击
    这是一个创建于 1361 天前的主题,其中的信息可能已经有所发展或是发生改变。
    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 1) .thenApplyAsync(i -> i+1) .thenApplyAsync(i -> i+1) .thenAccept(i -> System.out.println(i)); 

    thenApplyAsync()thenApply()这两个方法都需要等待前一个任务的返回值,那么thenApplyAsync()异步的含义是什么?

    14 条回复    2022-08-11 13:13:12 +08:00
    momocraft
        1
    momocraft  
       2022 年 8 月 4 日
    thenApplyAsync 的参数函数会跑在不同的线程
    dqzcwxb
        2
    dqzcwxb      2022 年 8 月 4 日
    所有带 Async 的方法都意味着会使用新的线程池去执行任务,如果你不指定则使用默认的 ForkJoinPool 线程池指定则使用你指定的线程池
    理论上也有可能会是同一个线程去执行,比如线程池就 1 个线程或者刚好调度到同一个线程
    Jooooooooo
        4
    Jooooooooo  
       2022 年 8 月 4 日
    你试着不用这个功能把 A, B, C 三个任务串起来写, 会非常恶心. 它这个是极大简化前后有关联的任务写法.

    至于异步的含义, 有可能是 D 依赖 C1, C2 的完成才能执行, 而 C1, C2 是可以并行跑的, C1 依赖 B, C2 依赖 A. 如果不用它提供的这个工具, 你自己要写这么一串, 代码会很长
    7911364440
        5
    7911364440  
    OP
       2022 年 8 月 4 日
    @dqzcwxb 我的疑惑就是 thenApplyAsync 虽然会使用新的线程去执行任务,但也还是要等待前一个任务的返回值,使用新的线程去执行任务的意义是什么呢?
    JsonNode
        6
    JsonNode  
       2022 年 8 月 4 日
    一个会阻塞主线程,一个不会?
    jiulang
        7
    jiulang  
       2022 年 8 月 4 日
    未必是新的线程,是从池里取出一个当前空闲的线程来执行,执行完就放到池里
    yazinnnn
        8
    yazinnnn  
       2022 年 8 月 4 日
    @7911364440

    public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action);
    如果直接使用这个 api 的话, 貌似跟 thenAccept 没啥区别


    public CompletionStage<Void> thenAcceptAsync(Consumer<? super T> action,
    Executor executor)
    如果用这个的话, 可以将后续任务切换到其他线程池中进行, 比如之前运行在 eventloop 线程, 接下来的任务是阻塞耗时操作, 那么可以切换到 worker 线程中进行
    msaionyc
        9
    msaionyc  
       2022 年 8 月 4 日 via iPhone
    不同场景使用不同的线程池是很有必要的,默认的线程池并不适用所有的场景
    wangyu17455
        10
    wangyu17455  
       2022 年 8 月 4 日   2
    不阻塞 io 线程就是意义,springboot 默认只给 tomcat200 条 io 线程,如果你的业务代码是异步的,返回了 CompletableFuture 或者 spring 的 Flux/Mono ,那就可以交给 netty 去调度你的代码,线程数量就不再会限制你的连接数,可以完全跑满 cpu 的性能而不会浪费大量的时间在线程切换上
    shyling
        11
    shyling  
       2022 年 8 月 4 日
    一个是跑异步,一个是跑同步
    nekoneko
        12
    nekoneko  
       2022 年 8 月 4 日
    10 楼说的对
    golangLover
        13
    golangLover  
       2022 年 8 月 9 日 via Android
    看了上面的解释,说实话我觉得其他人并不在回答楼主的问题。看看用户 1283822 的回答


    https://stackoverflow.com/questions/47489338/what-is-the-difference-between-thenapply-and-thenapplyasync-of-java-completablef
    Aresxue
        14
    Aresxue  
       2022 年 8 月 11 日
    因为大多数业务应用都是 io 密集型,这样可以更方便的压榨 cpu ,这么做的有 tomcat 、dubbo 、spring 、netty 等,接收请求的线程和处理线程一般都是分开的,业务代码这么做要看情况而定。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2999 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 84ms UTC 14:07 PVG 22:07 LAX 07:07 JFK 10:07
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86