定了,JDK 19 功能集冻结,JDK官方终于支持支持协程了


  • 发布流程

  • 特性

  • 核心特性-协程

    • 如何启用

  • 参考

从 JDK 19 的概述页面来看,JDK 19 处于 Rampdown Phase Two 阶段,整个功能集已被冻结,将不再对 JEP 进行改动


定了,JDK 19 功能集冻结,JDK官方终于支持支持协程了
在这里插入图片描述

官方文档地址

发布流程

可以看到整个发布流程

时间 节点
2022/06/09 Rampdown Phase One 第一阶段 (fork from main line)
2022/07/21 Rampdown Phase Two 第二阶段
2022/08/11 Initial Release Candidate 初始候选版本
2022/08/25 Final Release Candidate 最终候选版本
2022/09/20 General Availability 最终稳定版本

特性

最终确认Java 19 只有 7 个新特性:

编号 特性
405 Record Patterns (Preview) 记录模式
422 Linux/RISC-V Port Linux/RISC-V 移植
424 Foreign Function & Memory API (Preview) 外部函数和内存 API
425 Virtual Threads (Preview) 虚拟线程
426 Vector API (Fourth Incubator) 向量 API
427 Pattern Matching for switch (Third Preview) Switch 模式匹配
428 Structured Concurrency (Incubator) 结构化并发

核心特性-协程

其中最引人关注的当属特性425,虚拟线程即协程。一直以来golang以协程为优势,比java线程更轻量级,吞吐量更高。导致大多数中间件都转战使用golang去编写。jdk19开始支持协程,不知道后续会与golang擦出怎样的火花

简单使用。对于jdk19协程的简单使用,我们这里使用官方的demo

开发人员可以选择使用虚拟线程还是平台线程。下面是一个创建大量虚拟线程的示例程序。该程序首先获得一个 ExecutorService,它将为每个提交的任务创建一个新的虚拟线程。然后,它提交10000项任务,等待所有任务完成:

try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(010_000).forEach(i -> {
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1));
            return i;
        });
    });
}  // executor.close() is called implicitly, and waits

JDK 的虚拟线程调度程序是一个使用 ForkJoinPool,它以 FIFO 模式运行。调度程序的并行度是可用于调度虚拟线程的平台线程数。默认情况下,它等于可用处理器的数量,但可以使用系统属性 jdk.virtualThreadScheduler.parallelism 进行调整。请注意,此 ForkJoinPool 不同于在并行流的实现中使用的公共线程池,它以 LIFO 模式运行

本例中的任务是简单的代码(休眠一秒钟) ,现代硬件可以轻松支持10,000个虚拟线程并发运行这样的代码。在幕后,JDK 在少数操作系统线程上运行代码,可能只有一个线程。

如果这个程序使用 ExecutorService 为每个任务创建一个新的平台线程,比如 Executors.newCachedThreadPool () ,那么情况就会大不相同。ExecutorService 将尝试创建10,000个平台线程,从而创建10,000个 OS 线程,程序可能会崩溃,这取决于计算机和操作系统。

相反,如果程序使用从池中获取平台线程的 ExecutorService (例如 Executors.newFixedThreadPool (200)) ,情况也不会好到哪里去。ExecutorService 将创建200个平台线程,由所有10,000个任务共享,因此许多任务将按顺序运行,而不是并发运行,而且程序将需要很长时间才能完成。对于这个程序,一个有200个平台线程的池只能达到每秒200个任务的吞吐量,而虚拟线程达到每秒10,000个任务的吞吐量(在充分预热之后)。此外,如果示例程序中的10000被更改为1,000,000,那么该程序将提交1,000,000个任务,创建1,000,000个并发运行的虚拟线程,并且(在足够的预热之后)实现大约1,000,000任务/秒的吞吐量。

如果这个程序中的任务执行一秒钟的计算(例如,对一个巨大的数组进行排序)而不仅仅是休眠,那么增加超出处理器核心数量的线程数量将无济于事,无论它们是虚拟线程还是平台线程。虚拟线程并不是更快的线程ーー它们运行代码的速度并不比平台线程快。它们的存在是为了提供规模(更高的吞吐量) ,而不是速度(更低的延迟)。它们的数量可能比平台线程多得多,因此根据 Little’s Law,它们能够实现更高吞吐量所需的更高并发性。

更多说明可以去阅读官方文档

如何启用

目前虚拟线程在其他多线程语言中被广泛使用(例如 Go 中的协程 和 Erlang 中的进程,在 C++ 中也是一个稳定特性),但在 Java 中还是一个预览 API,默认禁用。如要在 JDK XX 上尝试该功能,则必须通过以下方法启用预览 API:

  • 使用 javac –release XX –enable-preview Main.java 编译程序,并使用 java –enable-preview Main 运行
  • 使用源代码启动器时,使用 java –release XX –enable-preview Main.java 运行程序
  • 使用 jshell 时,用 jshell –enable-preview 启动

可以看到默认禁用,说明还只是一个预览API不够稳定,需要后续优化稳定后开放使用

参考

  • jdk官方文档地址


原文始发于微信公众号(小奏技术):定了,JDK 19 功能集冻结,JDK官方终于支持支持协程了

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/29822.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!