JDK 21的发布标志着Java发展的一个重要里程碑。这是一个长期支持(LTS)版本,确保Oracle至少八年的稳定性和支持。在这个版本中,Java开发人员引入了几个新特性,包括虚拟线程、记录模式、switch语句的模式匹配、外部函数和内存API以及ZGC垃圾收集器。
虚拟线程的意义
在这些特性中,虚拟线程脱颖而出,成为并发Java应用程序领域的游戏规则改变者。虚拟线程有可能彻底改变开发人员编写和管理并发代码的方式。它们提供了额外的好处,使它们成为高吞吐量并发应用程序的理想选择。
虚拟线程的优势
虚拟线程带来了几个优势,使其有别于传统的平台线程:
l 高效的内存使用:与传统线程相比,虚拟线程消耗的内存要少得多。JVM智能地管理虚拟线程的内存,支持多个虚拟线程的重用和高效分配。
l 优化的CPU使用率:虚拟线程的CPU效率更高。JVM可以在同一个底层OS线程上调度多个虚拟线程,消除了上下文切换的开销。
l 易用性:虚拟线程更容易使用和管理。JVM负责它们的生命周期,消除了手动创建和销毁的需要。这简化了并发Java应用程序的开发和维护。
了解线程类型
为了理解虚拟线程的重要性,让我们简单地研究一下三种类型的线程:
1.操作系统线程(本机线程):这些是现代操作系统中的基本执行单元。每个操作系统线程都有自己的堆栈、程序计数器和寄存器组,由操作系统内核管理。
2.平台线程(传统Java线程):平台线程构建在操作系统线程之上,但由Java虚拟机(JVM)管理。它们提供了更有效的调度和资源利用。平台线程是以传统方式实现的java.lang.Thread的一个实例,作为操作系统线程的一个薄薄的包装。
3.虚拟线程:虚拟线程是java.lang的实例,线程不绑定到特定的操作系统线程。单个操作系统线程可以服务多个虚拟线程。虚拟线程甚至比传统线程更轻、更高效,它们可以用来提高并发Java应用程序的性能、可伸缩性和可靠性。
传统线的挑战
线程是并发服务器应用程序的构建块,近三十年来一直是Java不可或缺的一部分。不幸的是,传统Java线程的创建和维护成本很高。可用线程的数量是有限的,因为JDK将线程实现为操作系统(OS)线程的包装器。操作系统线程的成本很高,所以我们不能拥有太多的线程,这使得实现不适合每个请求一个线程的风格,这限制了Java服务器可以处理的并发请求的数量,从而影响了服务器应用程序的可伸缩性。
向线程共享的转变
经过一段时间,为了能够最大限度地扩展和利用硬件,java开发人员从每个请求一个线程的风格转变为线程共享风格。在线程共享中,请求处理代码不是从头到尾在一个线程上处理请求,而是在等待另一个I/O操作完成时将其线程返回到一个池中,以便该线程可以服务于其他请求。
这种细粒度的共享节省了线程,但需要异步编程技术。异步编程是一种复杂且容易出错的提高可伸缩性的方法,并且它与Java服务器应用程序中常见的每请求线程风格不兼容。
引入虚拟线程
虚拟线程提供了一个引人注目的解决方案,可以在增强并发性的同时保持每个请求一个线程的风格。它们不依赖于特定的操作系统线程,允许更大的并发性。虚拟线程仅在CPU受限的任务期间消耗操作系统线程。当它们遇到阻塞的I/O操作时,它们会自动挂起,而不会独占一个OS线程。创建和管理虚拟线程非常简单,消除了对池的需求。
虚拟线程是短暂的,执行特定的任务,并且数量丰富。平台线程是重量级的、长寿的,并且可能需要池化。使用虚拟线程保持了每个请求一个线程的风格,同时优化了硬件利用率。
JDK21的未来
需要注意的是,JDK 21的目标不是取代传统的线程实现,而是提供一种有效的替代方案。开发人员可以根据他们的具体需求,灵活地在虚拟线程和平台线程之间进行选择。
结论
Java开发人员长期依赖线程进行并发编程。随着JDK 21中虚拟线程的引入,在保持熟悉的编程风格的同时实现高并发变得更加容易。虚拟线程对于处理大量用户请求的服务器应用程序尤其有价值,可以在不断变化的环境中提供效率和可伸缩性。