quietin
V2EX  ›  Java

Java 中如何实现这样的功能

  •  
  •   quietin · Aug 18, 2017 · 5592 views
    This topic created in 3210 days ago, the information mentioned may be changed or developed.
    像 py 里用 tornado 进行 io 的话, 碰到 io 的代码, 使用 yield 直接异步, 可以等 io 回来之后, 拿到 io 的结果. 再从当前代码往下执行


    现在想在 java 里实现类似的功能(并发拿多个请求的结果), 但 java 异步要使用线程池, 这样的话, 主线程和线程池之间需要一个通讯, 如果用 countDownLatch 来进行通知的话, 主线程会阻塞(io 耗时久时); 因为要拿多个结果, 无法直接用主线程来完成

    现在需要在收到一个 http 请求后, 用线程池并发地取数据, 如果有一个线程返回数据的话, 主线程就可以返回.
    但是目前用这种线程池的做法感觉线程很差. java 的 future 要么是 get(阻塞), 要么是 void 的回调(结果无法 return)到上层.

    其实简单来说, 就是遇到一个 http 请求需要等待结果返回的情况下, 如何才能使吞吐量最大?
    还望大佬们指教.
    22 replies    2017-08-22 00:03:19 +08:00
    niuroumian
        1
    niuroumian  
       Aug 18, 2017 via iPhone
    用 BlockingQueue 在回掉函数里获取结果,然后主线程取出
    doing
        2
    doing  
       Aug 18, 2017
    Callable+FutureTask 不可以吗
    ghos
        3
    ghos  
       Aug 18, 2017
    CompletableFuture ?这个可以支持执行完进行回调的
    suantong
        4
    suantong  
       Aug 18, 2017 via Android
    简单问题你复杂化了。
    looplj
        5
    looplj  
       Aug 18, 2017
    可以看下 Vert.x,就是全部异步,IO 的时候还是要在 Block 线程池中执行,使用的时候配置一下线程池数量就可以了。

    其实用异步也只是增加一些并发量而已,QPS 的决定性因素还是 IO,这个也是 Servlet 还是主流的原因了。

    而且,Java 写这种异步很麻烦的。
    推荐用 Go 吧。
    lowzoom
        6
    lowzoom  
       Aug 18, 2017
    外层传个回调进来就可以了吧,为何一定要 return
    lujiajing1126
        7
    lujiajing1126  
       Aug 18, 2017 via iPhone
    Java 也有协程实现
    quietin
        8
    quietin  
    OP
       Aug 18, 2017
    @lowzoom 求详细
    quietin
        9
    quietin  
    OP
       Aug 18, 2017
    @lujiajing1126 有推荐的实现吗, 生产环境稳定可靠的
    mrsatangel
        10
    mrsatangel  
       Aug 18, 2017
    协程:quasar
    封装 IO: 裸写 nio/netty
    netty 和 quasar 都很稳定
    lowzoom
        11
    lowzoom  
       Aug 18, 2017   ❤️ 1
    CompletableFuture.supplyAsync(IO 函数)
    .thenAccept(外部传进来的回调函数)
    quietin
        12
    quietin  
    OP
       Aug 18, 2017
    @lowzoom 计算值是 Void, 这样 http 没法返回吧
    lowzoom
        13
    lowzoom  
       Aug 18, 2017
    贴个代码来看看
    dphdjy
        14
    dphdjy  
       Aug 18, 2017 via Android
    用 task 结束的时候 post 回去
    lujiajing1126
        15
    lujiajing1126  
       Aug 18, 2017 via iPhone
    @quietin 10 楼已经提到了
    rayingecho
        16
    rayingecho  
       Aug 18, 2017
    可以用 Kotlin 的协程,跟 Java 完美互操作,不存在隔阂了
    zhx1991
        17
    zhx1991  
       Aug 19, 2017
    你描述的功能就是 future 啊
    zhchyu999
        18
    zhchyu999  
       Aug 19, 2017
    yidinghe
        19
    yidinghe  
       Aug 19, 2017 via Android
    Netty 框架就是为了最大化网络吞吐量而编写的。
    micean
        20
    micean  
       Aug 20, 2017
    试用过 java 的伪协程框架,性能还不如走线程池写同步代码
    其实涉及到数据库操作的话,如果数据库不支持异步还是得挂线程去 wait 数据
    quietin
        21
    quietin  
    OP
       Aug 21, 2017
    @micean 主要是网络 io
    micean
        22
    micean  
       Aug 22, 2017
    @quietin java 毕竟不优雅,要么适应异步的写法,要么使用楼上的 kotlin 之类的
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   952 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 93c8b4a0 · 62ms · UTC 21:59 · PVG 05:59 · LAX 14:59 · JFK 17:59
    ♥ Do have faith in what you're doing.