Java“虚拟线程”被提交到JEP草案


Java也终于要有纤程、绿色线程啦,虚拟线程能大幅减少编写、维护和观察高吞吐量并发应用程序的工作量,这些应用程序通过虚拟线程充分利用可用硬件,这是一种成本显着降低的轻量级用户模式线程实现。这是一个预览功能
目标

  • 添加java.lang.Thread指定虚拟线程的附加实现,它将扩展到几 GB 堆上的数百万个活动实例,并表现出与现有线程(指定平台线程)几乎相同的行为。
  • 通过现有的 JDK 工具和工具接口,以尽可能类似于平台线程的方式支持虚拟线程的故障排除、调试和分析。

在过去的几十年中,开发人员一直广泛使用 Java 来编写并发应用程序,例如服务器和线程,特别是 java.lang.Thread,已成为他们的核心构建块。线程可以很好地表示并发的某些应用程序单元,例如事务,因为平台及其工具知道并跟踪它。
不幸的是,当前的 Thread 实现为每个 Java 线程消耗一个 OS 线程,而 OS 线程稀缺且成本高昂,远比套接字Socket多得多。这意味着现代服务器可以处理比操作系统线程多几个数量级的并发事务。
编写高吞吐量服务器软件的开发人员必须有效利用硬件以免浪费它,因此必须在事务之间共享线程。
首先通过使用线程池将线程借给事务以节省为每个线程创建新线程的成本,然后,如果这还不够,因为操作系统根本无法支持尽可能多的并发线程;这导致了异步编程风格,它不仅需要一组单独且不兼容的 API,而且打破了逻辑应用程序单元(事务)和平台单元(线程)之间的连接,这使得平台不知道应用程序的逻辑单位。结果,故障排除、观察、调试和分析变得非常困难,因为平台的上下文——线程——不再代表事务,因此不是很有用。为更困难的开发和维护购买更好的硬件利用率,这也转化为浪费。
然后,开发人员被迫在将并发的逻辑单元直接建模为线程的自然风格和浪费其硬件可以支持的大量吞吐量之间进行选择。
虚拟线程——用户模式实现java.lang.Thread——给我们两全其美的。在虚拟线程上使用相同的同步 API 时,这些廉价线程会阻塞,而不会阻塞任何宝贵的操作系统线程。硬件利用率接近最佳,允许高水平的并发性,从而实现高吞吐量,同时程序与 Java 平台的基于线程的设计及其工具保持和谐。
虚拟线程之于平台线程,就像虚拟内存之于物理 RAM:一种机制,通过自动有效地映射到底层“物理”资源,产生大量“虚拟”资源的错觉。
由于虚拟线程既便宜又丰富,线程使用模式预计会发生变化。
 
虚拟线程是 JDK 实现的 java.lang.Thread 的实例,它允许大量活动实例在同一进程中共存。它们可以使用java.lang.Thread.Builder接口创建,如下所示:
Thread thread = Thread.ofVirtual().name("duke").unstarted(runnable);

可以通过该Thread::isVirtual方法查询线程是否为虚拟线程。
JDK 通过在 Java 堆上存储它们的状态(包括堆栈)来实现虚拟线程。虚拟线程由Java类库中的调度器进行调度,其工作线程在虚拟线程执行时将虚拟线程挂载在其上,从而成为它们的载体;当虚拟线程挂起时:比如说,当它阻塞在一些 I/O 操作或 java.util.concurrent 同步构造上时,而同时这些虚拟线程的载体可以自由地运行任何其他任务。
当一个虚拟线程被从挂起状态解放恢复运行时,比如说,一个 I/O 操作已经完成,它就会被提交给调度程序,当其可用时,将在某个载体线程上挂载和恢复这个虚拟线程,不一定是它在之前运行的同一工作线程。这样,当一个虚拟线程执行阻塞操作时,就不会阻塞一个OS工作线程。
详细点击标题