CompletableFuture FutureTask 的错误使用案例 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
byte10
V2EX    Java

CompletableFuture FutureTask 的错误使用案例

  •  
  •   byte10 2022 年 5 月 10 日 1887 次点击
    这是一个创建于 1447 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一、背景

    在一些接口响应时间的优化中有一些任务是可以异步处理的,常常会用到这个线程池。但是有一些业务需要依赖异步任务的结果,那么就需要用到 CompletableFuture 或者 FutureTask ,或者在一些多任务并发执行的时候,CompletableFuture 可以提供一些方法让我们更容易的控制并发编程。

    二、常见的错误操作

    这种就是画蛇添足的做法,等于脱裤子放屁。

    所谓的异步

    第二种方式是把一些业务代码放在 get()方法之前去执行。这种是 oK 的,但是还有一个问题。如果异步任务是 IO 密集型,那么就需要解决线程池的问题。

    放中间

    第三种:使用额外的线程池,处理这个 IO 密集型任务。 自定义线程池

    总结

    使用 CompletableFuture 、FutureTask 的前提:

    1. 你的业务有异步的需求且需要知道任务执行的结果。比如是否执行完成,执行结果。
    2. 你的整个业务链中有不依赖这个异步任务结果的业务代码,这样就可以先执行这些中间业务代码。
    3. 这个中间业务代码( IO 阻塞或者非阻塞代码,非阻塞代码一般很快)的执行时间 W ,W 最好大于或者等于这个异步任务的执行时间。如果 W 执行很快,比如是非阻塞代码,那么这个异步任务的意义不大。

    注意事项:

    1. 如果这个异步任务是一个非阻塞代码(也就是计算密集型代码),那么直接用即可(底层是 ForkJoinPool)。这个在就不再阐述原理了,在线程池那集有讲过。
    2. 如果这个异步任务是一个 IO 阻塞型代码,那么就需要使用一个额外的自定义线程池去处理,这个线程池的大小取决于这个任务的 IO 和 cpu 时间比,还有和中间任务的时间比,大致确定范围即可。

    这些问题的详细描述在我的 B 站里 ,java 并发编程: https://www.bilibili.com/video/BV1CA4y1S7Pe? 这些都是 API 的使用,其实很无聊。但是错的人太多了,所以就讲一下这个问题。头大。。

    其他的场景就是多个任务同步执行的情况,可以使用 allOf ,compose 等,那么就不在这里给大家演示了。

    byte10
        1
    byte10  
    OP
       2022 年 5 月 11 日
    这么经典没人看,难道大家都这么强的吗 。
    golangLover
        2
    golangLover  
       2022 年 5 月 12 日 via Android
    我觉得你这个写法其实也没解决核心问题。很多时候业务的代码是有上下依赖的,正确的做法是用 cf 的 chainning 例如 thenAccept 和 thenapplu 之类,最后直接等待这个 cf.
    byte10
        3
    byte10  
    OP
       2022 年 5 月 12 日
    @golangLover 嗯 你要关注前提条件,首先用 CompletableFuture ,FutureTask 必须是有依赖结果的,否则直接用线程池异步处理就可以了。 我的讲解是:非依赖异步任务的中间业务,可以放在 get() 方法前面。有依赖异步任务结果的业务,那必须放在 get()后面。如果不存在 这样的中间业务代码,那么不要用 CompletableFuture ,请直接用线程池代替。

    当然如果有多个异步任务并行处理,CompletableFuture 还是很划算的,方便处理。

    另外你说的这个 thenAccept/whenComplete 并不能进行同步编程,不能满足业务需求,这一点非常的重要,一定要看到本质。先看需求,再看实现的方式,然后在看本质,如果看不到本质,就用侧代码去验证它。你说的那些方式只不过是实现需求的一种方案,本质还是线程池,你可以验证下,其实都一样。你一定要验证,同样都能完成一样的业务需求,不同的写法是否能给你带来的性能的提升。
    golangLover
        4
    golangLover  
       2022 年 5 月 12 日 via Android
    我只能讲用途有限吧,不过你的说话是没错的。至于直接用线程池,我不会这么做
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     859 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 41ms UTC 19:55 PVG 03:55 LAX 12:55 JFK 15:55
    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