V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
sagaxu
V2EX  ›  程序员

JVM 上的协程,真香

  •  
  •   sagaxu · 2018-12-05 16:25:13 +08:00 via Android · 10426 次点击
    这是一个创建于 2184 天前的主题,其中的信息可能已经有所发展或是发生改变。
    尝试把一个 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  
       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   ·   实用小工具   ·   1050 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 21:33 · PVG 05:33 · LAX 13:33 · JFK 16:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.