JVM 上的协程,真香 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
sagaxu
V2EX    程序员

JVM 上的协程,真香

  •  
  •   sgaxu 2018-12-05 16:25:13 +08:00 via Android 10869 次点击
    这是一个创建于 2510 天前的主题,其中的信息可能已经有所发展或是发生改变。
    尝试把一个 API 从 Future 重构成了 coroutine,代码行数减少很多,代码逻辑也更清晰易懂了。同步的代码写起来流畅多了,又少了一个用 go 的理由。
    46 条回复    2018-12-06 14:25:38 +08:00
    HsingChih
        1
    HsingChih  
       2018-12-05 16:34:11 +08:00
    你是用的什么框架,Quasar 还是 kilim ?
    BBCCBB
        2
    BBCCBB  
       2018-12-05 16:36:48 +08:00
    发图不留种, xxxxx
    sagaxu
        3
    sagaxu  
    OP
       2018-12-05 16:37:40 +08:00 via Android
    @HsingChih Kotlin + Vertx,前几日发布的 vertx 3.6,为所有异步方法自动合成了 suspend function,不用再写 await 了
    WispZhan
        4
    WispZhan  
       2018-12-05 16:39:59 +08:00 via Android
    然而 go 的协程资源成本低很多
    lihongjie0209
        5
    lihongjie0209  
       2018-12-05 16:40:07 +08:00
    有时候一个类库解决的问题非要用另外一种语言...
    luosuosile
        6
    luosuosile  
       2018-12-05 16:41:18 +08:00
    现在都不写 Java 的吗?后端有开始用 Kotlin 的吗。
    PDX
        7
    PDX  
       2018-12-05 16:47:52 +08:00 via iPhone
    @sagaxu 3.6 真的优化好多
    keepeye
        8
    keepeye  
       2018-12-05 17:01:16 +08:00
    coroutine 是单线程吗? goroutine 可以利用多核吗?小白不懂求教
    qiyuey
        9
    qiyuey  
       2018-12-05 17:07:50 +08:00
    @lihongjie0209 Kotlin:不仅仅是协程
    qiyuey
        10
    qiyuey  
       2018-12-05 17:12:13 +08:00
    @keepeye 都可以选
    sagaxu
        11
    sagaxu  
    OP
       2018-12-05 17:12:31 +08:00 via Android   2
    @WispZhan go 是 stackful 协程,kotlin 是 stackless 协程,一个 kotlin 协程内存占用还不到 1KB,go 每个协程要 2KB。
    @lihongjie0209 一年前换了 Kotlin,协程是今天才上的。并非因为一个库换的语言。
    @keepeye 线程数可以自己决定,vertx 部署了几个 instance 就有几个线程。
    @qiyuey Kotlin 值得拥有。
    GuuJiang
        12
    GuuJiang  
       2018-12-05 17:22:00 +08:00 via iPhone
    借地广告下自己撸的 coroutine 轮子,现在还处于玩具阶段,但是功能是完备的
    https://github.com/GuuJiang/Jacob
    lhx2008
        13
    lhx2008  
       2018-12-05 17:30:21 +08:00 via Android
    没 kotlin,直接用 webflux 的响应式编程也不错
    reus
        14
    reus  
       2018-12-05 17:32:12 +08:00
    换言之,go 用这种同步风格的东西已经六七年了,而且一直都很稳定,不用你改代码
    vert.x 遗留代码就会比较多吧,我猜。
    qiyuey
        15
    qiyuey  
       2018-12-05 18:51:40 +08:00
    @lhx2008 webflux 的问题在于链式调用过于复杂,可读性太低
    WispZhan
        16
    WispZhan  
       2018-12-05 20:15:11 +08:00 via Android
    @sagaxu 受教了,看来之前对 kotlin 和协程了解还是不深。
    hujianxin
        17
    hujianxin  
       2018-12-05 20:49:44 +08:00
    @keepeye goroutine 不是简单的协程,可以高效利用多核
    pythonee
        18
    pythonee  
       2018-12-05 21:05:43 +08:00 via iPhone
    有代码实例吗
    taowen
        19
    taowen  
       2018-12-05 21:27:24 +08:00
    @GuuJiang 应该不是完整实现吧?看代码量并不大啊。
    lueffy
        20
    lueffy  
       2018-12-05 21:31:39 +08:00 via iPhone
    马克
    cpdyj0
        21
    cpdyj0  
       2018-12-05 21:49:25 +08:00
    诶呀终于有这个功能了
    @sagaxu
    loqixh
        22
    loqixh  
       2018-12-05 21:51:47 +08:00
    c#用了多少年了, 你们才后知后觉. 还一直嘲笑 c#糖多太甜
    liuminghao233
        23
    liuminghao233  
       2018-12-05 22:09:30 +08:00 via iPhone
    c++早就用上了(
    janxin
        24
    janxin  
       2018-12-05 22:13:11 +08:00
    Kotlin 的 coroutine 还是和 go 的 goroutine 使用场景上不一样的。coroutine 本质上是调度,一些该 block 的操作还是 block 的。如果需要继续提升更高的性能,还是需要做 go 底层类似的异步转同步优化。这样改下来性能应该会比 go 更高。
    janxin
        25
    janxin  
       2018-12-05 22:15:25 +08:00
    另外支持 Kotlin 干死 Java,嗯嗯
    garfeildma
        26
    garfeildma  
       2018-12-05 22:54:48 +08:00 via Android
    @sagaxu 之前看 so 上 kotlin coroutines 作者解释过,kt 也是 stackful 的
    Tyanboot
        27
    Tyanboot  
    PRO
       2018-12-05 23:15:33 +08:00 via Android
    @keepeye
    @sagaxu

    kt + vertx 的情况下,kt 的协程是依靠 vertx 的线程池来调度的,然后 vertx 的一个实例还有 context 线程池和一个 worker 线程池,正常的代码都在 context 线程池上跑,包括协程也是。worker 线程池是在 executeBlocking 的时候用到的。这两个线程池默认好像是 4+8 吧。
    sagaxu
        28
    sagaxu  
    OP
       2018-12-05 23:51:53 +08:00
    @garfeildma 你可能记错了,Kotlin 的协程实现是 continuation-passing style,内部是个状态机。
    简介可以看他们 teamleader 的 ppt
    https://www.slideshare.net/elizarov/introduction-to-kotlin-coroutines


    @Tyanboot vertx 一个 instance 对应一个线程,线程数开到 4,如果 instance 小于 4,比如是 1,只能占用一个 CPU 核心。

    @taowen putty 代码里就有 coroutine 的状态机实现,其实用不了几行代码。

    @reus 如果都是 vertx 代码还好,可以无缝的跟协程一起用,海量的多线程阻塞代码是个问题。
    reus
        29
    reus  
       2018-12-06 00:05:42 +08:00
    @sagaxu 协程的通病了,和现有使用系统线程的多线程程序不容易配合。go 就没有这个问题,因为从一开始大家都是用 goroutine 的
    youngxhui
        30
    youngxhui  
       2018-12-06 07:58:52 +08:00 via Android
    听说 Java 现在内部也在实现协程,估计在日后的某个 JDK 版本内就有了
    fan123199
        31
    fan123199  
       2018-12-06 08:53:40 +08:00
    kotlin 才是现代语言。go 实在是有点原始,写个“列表中是否包含某个元素”都要写个 util。由于不支持泛型,每个类又要写一遍。
    loqixh
        32
    loqixh  
       2018-12-06 09:07:17 +08:00
    @reus goroutine 用底层 hack 的方式调度, 坑太多了, 时不是要注意调度问题. 像 c#一样全库异步化才是出路
    reus
        33
    reus  
       2018-12-06 09:15:39 +08:00
    @loqixh 例如什么坑? C#没有出路,过去没有,现在没有,以后也不会有。
    2225377fjs
        34
    2225377fjs  
       2018-12-06 09:29:35 +08:00
    stackless 的协程现在变成了优势了。。?
    Narcissu5
        35
    Narcissu5  
       2018-12-06 09:40:00 +08:00
    @reus 我觉得技术上的出路和普及度上的出路要分开看。Java 继续作死 C#未必没有机会,Service Mesh 也是个翻身的机会
    sagaxu
        36
    sagaxu  
    OP
       2018-12-06 09:53:01 +08:00 via Android
    @youngxhui loom 进 jvm 并且能用于生产环境,至少要到 java 17 了
    @fan123199 go2 一两年内应该能出来了,go 是现代 c 语言,不是现代语言
    @2225377fjs stackless 和 stackful 各有优劣,stackless 胜在轻量,轻到可以用它做 generator,但是调用开销比 stackful 稍大。
    @Narcissu5 C#有没有机会,就看 flag 和 bat 用的多不多,未来十年大部分互联网公司的技术骨干,多半是这些大厂输出的。
    garfeildma
        37
    garfeildma  
       2018-12-06 10:02:51 +08:00
    @sagaxu 主要是对 stackless 和 stackful 没有一个明确的定义,可以看看这个答案下边 Roman 的回复 https://stackoverflow.com/a/43023289/220029
    garfeildma
        38
    garfeildma  
       2018-12-06 10:04:16 +08:00
    @youngxhui Project Loom 吧,原来 Quasar 的作者在负责,不过听说阿里的 JDK 里边已经内置协程了
    slince
        39
    slince  
       2018-12-06 10:25:23 +08:00
    go 里一个关键词搞定的事情,java 要写一个类;是不是有线程伪装的协程都要存个疑
    loqixh
        40
    loqixh  
       2018-12-06 10:52:00 +08:00
    @reus 多用点你就知道了, go 我也是写个几个玩具的, 具体懒得说
    sagaxu
        41
    sagaxu  
    OP
       2018-12-06 11:11:01 +08:00 via Android
    @garfeildma Roman 这个回复里,stack*的定义是指 suspend 协程的时候,是否可以处于嵌套的调用栈中,是一种能力的描述,不是实现方式的描述。

    我们所说的 stack 否,是指创建协程的时候,会不会给这个协程创建一个专属的 stackframe。这是实现方式的描述,不是能力描述。
    csbde
        42
    csbde  
       2018-12-06 11:16:30 +08:00
    coroutine 比多线程好用
    qiyuey
        43
    qiyuey  
       2018-12-06 11:28:24 +08:00
    @slince Kotlin 是通过扩展方法实现的,可以达到关键字的简便程度,同时避免了额外的关键字定义,至于你说的 Class 那个是 Java 的事情,不是 Kotlin 的
    reus
        44
    reus  
       2018-12-06 11:29:58 +08:00
    @loqixh 切,我用了五六年了
    heiher
        45
    heiher  
       2018-12-06 14:17:59 +08:00 via Android
    协程又流行起来啦,看来不喜欢异步 API 的人挺多的。
    分享个自己撸的 C/C++协程

    https://github.com/heiher/hev-task-system
    hujianxin
        46
    hujianxin  
       2018-12-06 14:25:38 +08:00
    @reus 上面这位明显是菜鸡,别人说坑,他就说坑,问他啥坑,又不知道。。。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3446 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 04:42 PVG 12:42 LAX 21:42 JFK 00:42
    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