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

Java21 make Java great again

  •  5
     
  •   javak · 316 天前 via iPhone · 10400 次点击
    这是一个创建于 316 天前的主题,其中的信息可能已经有所发展或是发生改变。

    今天用了下 oracle 放出来的 Java21 早期版本,( Java21 正式版要今年 9.19 发布)。

    主要是为了测试虚拟线程( Java21 开始虚拟线程就是正式版了),这是是一个类是 go 协程的东西。

    我搞了 100 万个任务,每个任务一个线程模式,效果非常惊艳炸裂。cpu 、内存消耗非常稳定,也不高。相同情况用 Java 之前的普通线程( Java21 开始叫平台线程)试了下,吞吐完全不行,而且 CPU 、内存占用很高、起伏也很大。

    上面只是随手简单一测,并不严格和规范。但是效果我觉得还是能说明问题,那就是很强、很惊艳。我认为现在已经算是可以追平之前 go 吹爆的 go 协程特性了。

    所以就有了标题的感慨。

    第 1 条附言  ·  316 天前
    第一版预览,jep425
    https://openjdk.org/jeps/425

    第二版预览,jep436
    https://openjdk.org/jeps/436

    正式版,jep444
    https://openjdk.org/jeps/444

    每一版都有些变化和改进,要看 jep ,建议看最新版,不要只看第一版,现在这个时间点,不是为了特殊研究,只是从使用角度,直接看最新版就行了。
    98 条回复    2023-09-21 00:07:34 +08:00
    bunnyblueair
        1
    bunnyblueair  
       316 天前
    不错 希望摆脱 java 8
    dreamramon
        2
    dreamramon  
       316 天前
    已经在一个小项目里面用了虚拟线程 6 个月了,效果非常好。
    go 现在只剩能打包二进制文件这一个好处了。。。
    可惜,这 2 年火的 ai ,只能用 python ,主流的库都在 python 。。。
    Biluesgakki
        3
    Biluesgakki  
       316 天前
    希望新项目都开始用 21 吧
    wangxiaodong
        4
    wangxiaodong  
       316 天前   ❤️ 1
    @javak 虚拟线程的性能确实惊艳,但我最最喜欢的 JDK21 预览特性,却是“main 函数简化”和“JDK Foreign Function(取代 JNA 和 JNI)”,前者抛弃写 class 的桎梏,后者可以跟底层的畅快交互。
    https://congci.com/main/home/topics/java-programming/
    totoro52
        5
    totoro52  
       316 天前
    @dreamramon go 还是云原生的扛把子,毕竟机制就摆在那,没得比
    yazinnnn
        6
    yazinnnn  
       316 天前   ❤️ 3
    醒醒吧, 祖宗留下的 ThreadLocal 之法不可变

    Scoped Values 还在孵化阶段, 离正式发布至少还差两年
    SuperManNoPain
        7
    SuperManNoPain  
       316 天前   ❤️ 1
    MJGA !!
    boatrain1111
        8
    boatrain1111  
       316 天前
    确实很惊艳,奈何只能自己玩玩,公司的项目还是 jdk8
    hhjswf
        9
    hhjswf  
       316 天前 via Android
    怎么感觉有点伪需求。
    这种大量虚线程只能处理计算型任务吧? Java 里大部分痛点是 io 型吧?
    dqzcwxb
        10
    dqzcwxb  
       316 天前
    virtual thread 虚拟线程,直接把它当成当成对象去理解就行
    创建 100 万个虚拟线程等于创建 100 万个对象罢了,实际上创建的平台线程(不被锁定的情况下)还是 cpu-1 的数量
    wangxiaodong
        11
    wangxiaodong  
       316 天前
    @hhjswf 并不伪,假设有两件事情要解决,我先解决“用户空间”的线程接待能力,也算搞定了 50%了。I/O 层面的可以再来个 JEP 来处理。
    dqzcwxb
        12
    dqzcwxb  
       316 天前   ❤️ 5
    @hhjswf #9 你完全说反了,虚拟线程对 cpu 密集型任务提升很少对 io 密集型任务提升很大
    hakim
        13
    hakim  
       316 天前
    2 楼说的是个问题,ai 相关的主流库都在 python ,想用 java 写个 side project 不容易
    ql562482472
        14
    ql562482472  
       316 天前
    @wangxiaodong #4 FFI 没进 21
    Jxnujason
        15
    Jxnujason  
       316 天前
    你更任你更,工作开发继续 jdk8
    monkeyWie
        16
    monkeyWie  
       316 天前
    虚拟线程不能用 synchronized 的问题解决了吗,反正只要所有框架的支持了我就直接升上去,到时候就可以把那该死的 threads.threads.max 直接给干掉了
    fanxasy
        17
    fanxasy  
       316 天前   ❤️ 1
    虚拟线程+GraalVM Native Image 赢!🐶
    cheng6563
        18
    cheng6563  
       316 天前
    21 是 LTS 吗?来的真晚啊总算是来了
    Narcissu5
        19
    Narcissu5  
       316 天前
    @hhjswf 虚拟线程就是解决 IO 问题的
    acapla
        20
    acapla  
       316 天前   ❤️ 3
    期待 chatgpt 早日学会,然后教给我。。
    wenbingkun
        21
    wenbingkun  
       316 天前
    继续 jdk8 ,祖宗之法不可变🐶
    diagnostics
        22
    diagnostics  
       316 天前
    既然是 Java 的爱好者,那么连看完 JEP-425 的时间都没吗?这玩意用 actor 也差不多吧?只不过相比 Actor 代码改动不大而已。
    jjx
        23
    jjx  
       316 天前
    喜欢 go 的, 主要就是不想搞 java 那套
    所以,不会因为这个特性从 go 转到 java
    LeegoYih
        24
    LeegoYih  
       316 天前   ❤️ 6
    喜报:Java 好起来了
    悲报:八股文更多了
    chuck1in
        25
    chuck1in  
       316 天前
    @dreamramon springboot3 不是原生支持云原生吗。
    wangxiaodong
        26
    wangxiaodong  
       316 天前
    @diagnostics 可贵的一点是,虚拟线程对 Thread 池的 API 几乎完全兼容的,不大动就能兼容 Java 老项目,你 Actor 可是引入挺多依赖嘛。

    @ql562482472 JDK Foreign Function 也在 JDK21 预览特性列表中的。
    voidmnwzp
        27
    voidmnwzp  
       316 天前
    1.国内 jdk 版本超过 8 的公司不足 5%
    voidmnwzp
        28
    voidmnwzp  
       316 天前
    TWorldIsNButThis
        29
    TWorldIsNButThis  
       316 天前 via iPhone
    @diagnostics 还在 actor
    Scala 都不整这个玩 fiber 了
    voidmnwzp
        30
    voidmnwzp  
       316 天前
    @voidmnwzp #28 2.go func(){} 和 Thread.startVirtualThread(() -> {...}); 谁更简洁一目了然
    wangxiaodong
        31
    wangxiaodong  
       316 天前   ❤️ 8
    @voidmnwzp 提案上作者也说了,本来想用 go x()或 await/async 的方式,但为了让以前用 Thread API 的老程序受益,就直接改造 Thread 了,人家并不是不能更简化,人家是格局大!
    whileFalse
        32
    whileFalse  
       316 天前 via Android
    @SuperManNoPain 介个怎么发音
    twofox
        33
    twofox  
       316 天前
    我有个问题,既然虚拟线程不是真正的多线程。那我的数据库事务是不是都可以用同一个了
    mmdsun
        34
    mmdsun  
       316 天前
    手里项目已经是 spring boot 3.1 + JDK 20 了, 坐等 JDK 21 更新
    yty2012g
        35
    yty2012g  
       316 天前
    21 的虚拟线程解决 ThreadLocal 的问题了么?我记得好像是这个版本的还不支持 ThreadLocal 。
    Morii
        37
    Morii  
       316 天前
    某国民级的游戏服务端刚刚从 7 升级到 8....
    Bazingal
        38
    Bazingal  
       316 天前
    @totoro52 请教下是什么机制 go 有其它语言做不到的
    yty2012g
        39
    yty2012g  
       316 天前
    @mgzu #36 感谢感谢。我们现在各种 wrap ExecutorSerivce 来传递各种各样的 ThreadLocal Context ,不知道换了还能不能生效了
    monkeyWie
        40
    monkeyWie  
       316 天前
    @mgzu 这点就足够吊打 go 协程了
    yusheng88
        41
    yusheng88  
       316 天前 via Android   ❤️ 1
    虚拟线程主要解决 io 密集型任务导致的线程数多(内存占用多),上下文切换成本高问题。目前的上述问题的解决方案是 netty ,reactive 相关框架,但写法不直观。重点还是要发送请求的工具类也要支持非阻塞的。单纯使用虚拟线程,但 Java 的请求相关类没做改造的话,意义不大。
    yusheng88
        42
    yusheng88  
       316 天前 via Android
    jdk21 出来的话,应该会推动很多类库更新
    nikenidage1
        43
    nikenidage1  
       316 天前
    其实没用的,你看 C#,主流语言里第一个实现 async/await 协程的,也没见到增加多少使用者。
    使用某一个语言,往往不是因为这个语言是否有哪些特性、是否优秀。更多的因素是政治和历史原因
    Uplay
        44
    Uplay  
       316 天前
    @nikenidage1 中肯,感觉都是惯性
    ychost
        45
    ychost  
       316 天前   ❤️ 1
    已经用了 kotlin 的无栈协程,性能提升非常好
    voidmnwzp
        46
    voidmnwzp  
       316 天前
    go 的所有并发原语(mutex,channel)都是基于协程实现的,如果 jdk 单纯加了个虚拟线程,synchronized ,reenterLock 底层实现不变那也没啥意义,而且也不知道 jdk 的协程调度是否就比 go 的 gmp 高明
    voidmnwzp
        47
    voidmnwzp  
       316 天前
    jdk 的 io 库 还是 bio 那套,要用 nio 就得上 netty ,但 netty 这种异步基于事件的处理模式远不如 go 通过协程包装的伪 bio 模式直观简单
    Masoud2023
        48
    Masoud2023  
       316 天前   ❤️ 24
    你说的对,但是《 Java8 》是由 Oracle 自主研发的一款虚拟机。游戏发生在一个被称作「多线程」的幻想世界,在这里,被 jdk 选中的 Callable 将被授予「 CompletableFuture 」,导引线程之力。你将扮演一位名为「小公司程序员」的神秘角色只能在苦逼的编码中邂逅性格各异、能力独特的业务代码,和他们一起创造新屎坑,找回失散的劳动法——同时,逐步发掘「异步」的真相。
    mmdsun
        49
    mmdsun  
       316 天前
    @yazinnnn
    现在 Java 高并发应该流行 Reactive Programming ? ThreadLocal 不是什么好设计了吧?与反应式也完全不兼容。
    spring 新框架 webflux 也是支持,用的是 Context 传递之和当前操作,只与 Flux 和 Mono 相关。

    JDK9 也是新加了 Reactive Streams API 的支持,假设不用 spring webflux 单独用 Rxjava 和 Project Reactor 用链式操作符传递也够了。完全可以不用 ThreadLocal
    yazinnnn
        50
    yazinnnn  
       316 天前
    @voidmnwzp
    loom 对 bio 有提升

    如果你写 netty 之类的 nio 代码很快乐,可以不用理会 loom, 不快乐的话可以切换到 kotlin 协程, 或者切换到 loom+bio
    oldshensheep
        51
    oldshensheep  
       316 天前
    还有个更好的消息,GraalVM 的免费版本增加了一个 Oracle GraalVM ,这个是完全免费使用,允许商业使用的。而且可以使用 EE 版本的很多功能,比如 PGO ,G1GC ,压缩指针。这些功能在开源的版本当中是没有的。

    https://medium.com/graalvm/a-new-graalvm-release-and-new-free-license-4aab483692f5
    SeaTac
        52
    SeaTac  
       316 天前
    我们内部有一个好几千人的活跃 slack channel ,讨论如何解决 service 在从 jdk8 migrate 到 17 当中出现的问题
    aaronnew89
        53
    aaronnew89  
       316 天前 via Android
    @oldshensheep 能把多语言支持完全开源允许商用就好了
    fox0001
        54
    fox0001  
       316 天前 via Android
    第一次看到虚拟线程的介绍就震惊了。虽然很期待,但是,用起来才是正道。
    lesismal
        55
    lesismal  
       316 天前   ❤️ 1
    越是挣扎,越是真的要没落了。
    kenvix
        56
    kenvix  
       316 天前
    @hhjswf 你在说什么,计算任务直接 new Thread 朴素平台线程就行了, 甚至线程池都不需要
    kenvix
        57
    kenvix  
       316 天前
    @voidmnwzp 我觉得这就是差异化竞争,要这种你可以选用同样的 Java 体系的 Kotlin Coroutines
    diagnostics
        58
    diagnostics  
       316 天前
    @wangxiaodong #26
    @TWorldIsNButThis #29

    对对对,你俩是真懂。gRPC benchmark 里 scala-akka 去年还是前几,OP 说的变革,Fibers 能做的,actor 也能做个 80%,更不用说 VT 现在连线程公平性都没搞出来( JEP-425 的时候)背后一大堆隐藏的性能 BUG 。

    要讨论可以,先 follow up 行业知识再来,JEP-425 都没看完都指点江山了?
    impossibleshen
        59
    impossibleshen  
       316 天前
    @seaiaddca 怎么加入呢?有没有啥电报群啊什么的
    diagnostics
        60
    diagnostics  
       316 天前
    @yusheng88 #41 哥们你是懂得,帖内太多半桶水半吊子的指点江山了
    HaroldFinchNYC
        61
    HaroldFinchNYC  
       316 天前
    @Morii 王者农药?
    javak
        62
    javak  
    OP
       316 天前
    @diagnostics #58

    第一版预览,jep425
    https://openjdk.org/jeps/425

    第二版预览,jep436
    https://openjdk.org/jeps/436

    正式版,jep444
    https://openjdk.org/jeps/444

    每一版都有些变化和改进。
    zhouquanbest
        63
    zhouquanbest  
       316 天前
    还是 Kotlin 吧 别挣扎了
    yangyaofei
        64
    yangyaofei  
       316 天前
    更关心 String Template, 可以愉快的用类似 python 的 f-string 方式写 String 了. 至于性能什么的, 小作坊的自行车没机会上高速
    Morii
        65
    Morii  
       316 天前
    @HaroldFinchNYC

    不是哈哈
    yangyaofei
        67
    yangyaofei  
       316 天前
    @oldshensheep 用过不是很好用, 最后用了 com.antkorwin:better-strings:0.5 , 但是也就那样, IDE 的支持也一般吧, 而且还需要构建环境上加上一堆设置.
    RainCats
        68
    RainCats  
       316 天前
    @dreamramon 大佬看看有没空拉一帮同道去把那些库用 Java 整一下[坏笑]
    SeaTac
        69
    SeaTac  
       316 天前 via iPhone
    @impossibleshen
    没有 公司内部的 channel
    dreamlike
        70
    dreamlike  
       316 天前
    virtual thread 目前 public 的 api 都太简单了,不如 kt 可以微操调度,所以我还搞了这个玩意 https://github.com/dreamlike-ocean/UnsafeVirtualThread ,来搞手操调度,指定调度器,捞 carrierThread
    virtual thread 好处对我来说有两处:
    1,是沟通 Reactive 到 Blocking 的桥梁,我可以低成本来复用老的 BIO 生态,比如我就喜欢开虚拟线程跑 jdbc+myabtis/hibernate,比 hibernate reactive 好用多了
    2,我可以低成本将异步转同步,比如说 Future.await ,直接捞 continuation api 起来自己做调度也很好玩,对于 reactive 生态来说就无需引入 kotlin ,也无需被无栈协程的染色效应困扰
    Ericcccccccc
        71
    Ericcccccccc  
       316 天前   ❤️ 1
    最近 java 最大的一个优化应该是推广 zgc, 10ms 以内.
    jklove123bai
        72
    jklove123bai  
       316 天前
    @Morii 梦幻西游?
    dbpe
        73
    dbpe  
       316 天前
    @Ericcccccccc zgc 话说这玩意代价不是减低吞吐么?还是说我 Out 了..最近这个代价也解决了?
    javak
        74
    javak  
    OP
       316 天前 via iPhone
    @dbpe 吞吐降低不多,还有监控时都懂三倍内存问题,不好解决
    dqzcwxb
        75
    dqzcwxb  
       316 天前
    @javak #74 jdk21 要上 zgc 分代并取消多重映射,三倍内存的问题就没了
    javak
        76
    javak  
    OP
       315 天前 via iPhone
    @dqzcwxb 太棒了,我要去研究下分代 zgc 了
    lixintcwdsg
        77
    lixintcwdsg  
       315 天前
    现在 99%的线程池的确可以用虚拟线程代替,尤其是是 web 应用,大量下游各种调用的。
    一些老框架会焕发青春,比如一些用 netty 改造的 client ,有了虚拟线程就没这个必要了就直接用线程池+同步代码就可以。
    还有就是大部分 reactive 场景其实都是不需要的,改回同步代码即可
    beijinglowb
        78
    beijinglowb  
       315 天前
    可惜屎山迭代的难度不亚于重写了
    humpy
        79
    humpy  
       315 天前 via iPhone
    相比这个,我更喜欢的还是终于要有语言层面的 nullability 了,kotlin 我唯一喜欢的 feature 。以后就不用写 @Nullable 注解了

    https://mail.openjdk.org/pipermail/valhalla-spec-experts/2023-May/002276.html
    Ericcccccccc
        80
    Ericcccccccc  
       315 天前
    @dbpe 官方的宣传是大多数时候 stw 时间能控制在 1ms 以内, 并且和堆大小无关.
    winterbells
        81
    winterbells  
       315 天前 via Android
    @acapla 这就是我的愿望了,有些新的东西不是胡说就是提示训练集只到 2021 年
    karottc
        82
    karottc  
       315 天前 via iPhone
    我也一直在等正式版发布,我在自己本地已经在用早期版本了,不过最新的早期版本 jdk21-ea-27 ,在我的社区版的 idea 有个 bug ,timeunit 这个类识别有问题。

    https://youtrack.jetbrains.com/issue/IDEA-321080

    不知道是 oracle 的问题还是 idea 的问题。除了这个别的都很好,而且 zgc 的三倍内存问题已经解决了。


    我的本地脚本任务用虚拟线程爽的飞起,因为我经常需要帮老板从 cdn 上下载几十万的音频和图片,现在这个任务直接起飞。
    dif
        83
    dif  
       315 天前
    其他生态跟不上没啥用
    flyqie
        84
    flyqie  
       315 天前   ❤️ 1
    @Morii #37

    搜了下相关文章,感觉。。开心消消乐?

    王者荣耀这种肯定不适合用 java 。。
    kenvix
        85
    kenvix  
       315 天前
    @zhouquanbest kotlin 协程最大的问题是生态,一旦调用的库用到了阻塞 IO ,性能马上退化到和传统 Java 线程池一个水平了
    dqzcwxb
        86
    dqzcwxb  
       315 天前
    @dif #83 说出这话就说明你其实根本就没细看过,虚拟线程没有新增关键字只需要替换下线程池实现即可对旧代码非常友好,甚至框架或者组件如果本身就支持线程池替换的话连包都不用重新发,开发者(我们)把线程池替换一下就完事了
    需要关注的是 sync threadlocal 以及大量虚拟线程中创建的对象,但是这些会在 jdk21 中进行优化和处理
    dqzcwxb
        87
    dqzcwxb  
       315 天前
    @karottc #82 你可以试试用 forkjoin 线程池去跑你的任务,我预计应该效果差不多
    Leviathann
        88
    Leviathann  
       315 天前
    @kenvix 所以虚拟线程对 kotlin 也是利器,阻塞的调用可以用 virtual thread dispatcher
    dqzcwxb
        89
    dqzcwxb  
       315 天前   ❤️ 1
    @Ericcccccccc #71 实际上是承诺 stw 在 1ms 内 实际平均是 0.05ms
    zgc 目前的吞吐下降和三倍内存问题会在 jdk21 推出 zgc 分代后得到优化和解决
    jdk21 virtual thread 和 zgc 是性能提升大杀器,而且这两个对开发者非常友好可以做到开箱即用
    dif
        90
    dif  
       313 天前
    @dqzcwxb 你大概没理解我意思。我的意思是我升级到 21 ,其他组件不支持这么高版本。例如我一直想升级到 java17 ,但 impala 驱动不支持(最高支持到 java11 ,我谢谢它,还好不是 java8 ),所以,java17 玩得再花,我也没办法升级。类似的场景有很多。
    diagnostics
        91
    diagnostics  
       313 天前
    @Ericcccccccc #80 听起来非常像 C4 Garbage Collector
    diagnostics
        92
    diagnostics  
       313 天前
    @javak #62 我的观点是,无论是 Fiber 还是 Reactive ,都是在简化多核编程的难度,但 Fibre 能保持 `thread-pre-request` style 的简单性,而 Reactive 更复杂,所以你觉得效果炸裂只是你没接触、用过 Reactive

    包括 ZGC 也是用 Azul C4 论文剩下的东西,俗称捡垃圾。

    所以 Java 21 不会发生多大的变革吧,Java 一直是蓝领语言,Java21 只能说终于跟上了时代的脚步
    javak
        93
    javak  
    OP
       313 天前 via iPhone
    @diagnostics 同意啊,能跟上时代对我来说就是惊艳,就是那种不用换语言,用 Java 终于也能跟上时代了的感觉
    dqzcwxb
        94
    dqzcwxb  
       313 天前   ❤️ 1
    @dif #90 我跟你说的又不冲突,你说的是不支持的情况,我说的是很多包不需要兼容就可以直接升级到 21 因为虚拟线程并没有破坏之前的线程相关 api 而是扩展和兼容
    你有你的难处,但是这并不代表整个生态就会因为这个而停滞因为大部分都是可以无损升级的,只是你和部分人部分包会是个例,比如之前用 unsafe 的从 sun.misc 改到 jdk.internal.misc
    dif
        95
    dif  
       313 天前
    @dqzcwxb 明白你得意思,你的维度指的是针对线程相关 API 可以无缝切换,例如 JDK1.7 的 hashmap 和 JDK1.8 的 hashmap ,虽然底层实现变了,但对外 API 没变化。
    我的维度是,我想用这个东西,可惜一些历史包袱只能让我望洋兴叹。
    Aresxue
        96
    Aresxue  
       312 天前
    synchronized 和 ThreadLocal 不解决没法推广到业务,尤其是 ThreadLocal 的隐患太大了,希望能快点搞定吧
    javak
        97
    javak  
    OP
       312 天前 via iPhone
    @Aresxue 具体讲讲是啥问题,给个复现场景我去试试
    BigMaMa123
        98
    BigMaMa123  
       219 天前
    我们这已经大部分应用都到 17 了,21 规划落地中
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2722 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 41ms · UTC 11:21 · PVG 19:21 · LAX 04:21 · JFK 07:21
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.