• 请不要在回答技术问题时复制粘贴 AI 生成的内容
RRRSSS
V2EX  ›  程序员

Java 异步问题

  •  1
     
  •   RRRSSS · Mar 31, 2020 · 4639 views
    This topic created in 2266 days ago, the information mentioned may be changed or developed.

    现在我负责一个服务,主要是融合功能,根据传过来的参数,来调用上游的 A 、B 、C 三个 dubbo 服务,三个服务相互没有依赖,超时就丢弃,无所谓,然后拿到数据把他们 merge 一下,返回给下游。

    这个时候,A B C 三个服务 dubbo 超时设置的都是 200ms,我想异步调用他们,就使用 CompletableFuture,然后自定线程池处理的。但有人说高 IO 不要用 CompletableFuture,那怎么做这个异步呢?

    求解

    Supplement 1  ·  Mar 31, 2020
    看了大家的留言,自己再研究了一下,也问了公司同事,应该是这样的:

    CompletableFuture 默认使用线程池是 ForkJoinPool,而 ForkJoinPool 默认的线程数是 CPU 核数 - 1,擅长处理 CPU 密集型任务,而 IO 密集型任务需要自己合理配置的线程池(至于怎么设置,有经验问题,也可以压测慢慢调整,这个属于 JVM 调优部分)。
    20 replies    2020-04-01 10:28:33 +08:00
    RRRSSS
        2
    RRRSSS  
    OP
       Mar 31, 2020
    @127000 这个我看到了,不过需要 3 个上游都改接口,沟通成本太大,所以想着自己这边做。
    Foredoomed
        3
    Foredoomed  
       Mar 31, 2020
    自己定义个线程池, 然后用 CompletableFuture.runAsync(Runnable, Executor)
    RRRSSS
        4
    RRRSSS  
    OP
       Mar 31, 2020
    @Foredoomed 现在就是这么做的,关键是线程池定义多大,异步我了解得不多,我看网上说的是 CompletableFuture 适合 CPU 密集型任务,但是我这个是 高 IO 任务。
    ayavvv
        5
    ayavvv  
       Mar 31, 2020
    为什么 CompletableFuture 适合 CPU 密集型任务不适合高 IO 任务?
    直接用 Future 行不行?
    Jafee
        6
    Jafee  
       Mar 31, 2020
    不如先找找 CompletableFuture 不适合 I/O 操作的原因再排除 CompletableFuture 。(个人能力有限,没想到是什么原因导致的这个规则)

    “如果你并行的工作单元还涉及等待 I/O 的操作(包括网络连接等待),那么使用 CompletableFuture 灵活性更好。(与并行流相比较)” —— 《 Java 8 实战》
    Foredoomed
        7
    Foredoomed  
       Mar 31, 2020
    线程池设个最大线程数就行了,不用太精确。你只要做压力测试就行了,网上又不是都对的。
    optional
        8
    optional  
       Mar 31, 2020
    同步 call 都挺蛋疼,只能用线程池,可能线程池可以开大一点。
    yqsas
        9
    yqsas  
       Mar 31, 2020 via iPhone
    Aresxue
        10
    Aresxue  
       Mar 31, 2020
    CompletableFuture 是最佳方案,dubbo 自己的异步调用就支持。话说 IO 多才更适合使用 CompletableFuture, 能让 CPU 更充分利用,谁说不利于高 IO 的?我能想到的只是高 IO 对系统危害比较大, 以及失败及异常处理较为复杂。
    NeinChn
        11
    NeinChn  
       Mar 31, 2020
    记错了吧,绝大部分情况下请不要开多线程跑 CPU 密集型任务
    除非是单机就你一个请求在跑的场景,比如客户端,单机训练
    IO 操作只要是可以并行的,建议都并行跑.
    wysnylc
        12
    wysnylc  
       Mar 31, 2020
    @Jafee #6 计算密集型时设定线程池为虚拟核心数即可,IO 密集型则根据实际任务决定
    CompletableFuture 和 parallelStream 一样默认使用 ForkJoinPool 的线程池,ForkJoinPool 默认线程数是虚拟核心数
    所以 CompletableFuture 默认适合计算密集型,需要 IO 密集型则要自己定义线程池
    说 CompletableFuture 不适应 IO 密集型的要么是个半吊子,要么故意说一半藏一半误导别人,非蠢即坏
    nickchenyx
        13
    nickchenyx  
       Mar 31, 2020
    基本上还是一个 CompletableFuture + 自定义线程池解决这种问题的,不过这也有缺陷。

    Q:A 、B 、C 三个接口耗时不同,例如 C 不稳定,rt 比 A 、B 高很多,这时候就会因为 C 的 rt 影响整体的吞吐
    A: 线程池隔离,使用独立的线程池资源,隔离 C 的访问调用
    Q:C 的访问隔离了之后,如何处理 C 访问过慢的问题呢
    A:抛弃策略处理,或者使用 熔断 + FallbackFactory 构造默认返回

    说到这里基本就是 hystrix 做的事情了,各种熔断时间配置,资源隔离的颗粒度,这都是可以看 hystrix 的文档可以看到的。

    (有人说高 IO 不要用 CompletableFuture 这个问题,我觉得可能是因为底层还是使用 ForkJoin 的方式在处理任务,高延迟的任务会影响整理进度吧? 疯狂猜测
    LeeSeoung
        14
    LeeSeoung  
       Mar 31, 2020
    CompletableFuture 、CompositeFuture 。。= =我一度以为我记错了,原来这两个不一样的。。偏题了
    xiaoidea
        15
    xiaoidea  
       Mar 31, 2020
    我就是开线程池的
    bringyou
        16
    bringyou  
       Mar 31, 2020
    估计是因为 CompletableFuture 的 runAsync 等不带线程池入参的方法,使用的是默认的 forkJoinPool,这个线程池的线程数量是固定的 cpu 数目,且是整个 JVM 共享的,不太适合跑高 IO 应用。
    建议使用带线程池入参的方法,传进去自定义线程池。这个自定义线程池的最大线程数可以设置高一点。举个例子,[kotlin 里面跑 IO 协程的调度器,设置的最少 64 个线程]( https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/src/scheduling/Dispatcher.kt#L17)
    gaius
        17
    gaius  
       Mar 31, 2020 via Android
    可以指定自定义的线程池
    renyijiu
        18
    renyijiu  
       Mar 31, 2020
    制定一个线程池就好了,常用的 io 型数量可以 cpu * 2 + 1
    1424659514
        19
    1424659514  
       Apr 1, 2020
    CompletableFuture 指定一个线程池就可以了, 用这个方法

    runAsync(Runnable runnable,Executor executor)
    sagaxu
        20
    sagaxu  
       Apr 1, 2020 via Android
    CompletableFuture 用 ForkJoinPool 线程数少不擅长 IO 密集型?正好相反,所有擅长 IO 密集型的解决方案,核心思想之一就是减少线程数。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2726 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 140ms · UTC 05:58 · PVG 13:58 · LAX 22:58 · JFK 01:58
    ♥ Do have faith in what you're doing.