讲师中心 微信公众号
AI工具推荐 视频效率加速

Java并发演进:从绿色线程到虚拟线程的调度机制解析

云萱君_7393

云萱君_7393

发布时间:2025-11-11 14:52:01

|

342人浏览过

|

来源于php中文网

原创

Java并发演进:从绿色线程到虚拟线程的调度机制解析

java的并发模型经历了从绿色线程到虚拟线程的演进。绿色线程采用m:1调度,将多个用户线程映射到一个操作系统线程,存在性能瓶颈。虚拟线程则引入m:n调度,将大量虚拟线程高效地调度到少量操作系统线程上运行,显著提升了并发应用的吞量和可扩展性,解决了传统绿色线程的局限性,是现代java平台轻量级并发的关键。

深入理解Java线程调度机制

在Java平台中,线程是实现并发编程的基本单元。随着Java技术的发展,其对线程的实现和调度机制也经历了多次重要的演进。理解不同线程类型的调度模型对于编写高效、可扩展的并发应用至关重要。

1. 平台线程(Platform Threads)

平台线程是目前Java应用中最常见的线程类型,它直接封装了操作系统(OS)线程。这种模型采用1:1的映射关系,即一个Java平台线程对应一个操作系统线程。这意味着Java虚拟机(JVM)会为每个平台线程向操作系统请求一个内核线程,由操作系统负责其调度。

  • 特点:
    • 与操作系统线程紧密绑定,调度开销相对较高。
    • 可以充分利用多核处理器的并行能力。
    • 创建和管理成本较高,限制了其数量。

2. 绿色线程(Green Threads)

绿色线程是Java 1.1版本中引入的一种用户态线程实现,其设计目的是在操作系统线程尚不成熟和普及的年代提供轻量级并发。绿色线程的调度完全由JVM在用户空间完成,不依赖于操作系统内核。

  • 调度模型: 绿色线程采用M:1的调度模型。这意味着大量的绿色线程(M)被映射并运行在单个操作系统线程(1)之上。
  • 工作原理: JVM内部有一个调度器负责在这些绿色线程之间切换。当一个绿色线程执行I/O操作或调用yield()时,调度器会将CPU控制权交给另一个绿色线程。
  • 局限性:
    • 无法利用多核并行: 由于所有绿色线程都运行在同一个操作系统线程上,即使系统有多个CPU核心,绿色线程也无法实现真正的并行计算,只能通过时间片轮转实现并发。
    • 阻塞问题: 如果一个绿色线程执行了阻塞I/O操作(例如,等待网络响应),那么它所依附的那个唯一的操作系统线程也会被阻塞,导致所有其他绿色线程都无法运行,严重影响吞吐量。
    • 性能瓶颈: 随着操作系统线程的成熟和性能提升,绿色线程的性能优势逐渐消失,并最终被平台线程所取代。

3. 虚拟线程(Virtual Threads)

虚拟线程是Java 19作为预览功能引入,并在Java 21中正式发布的一项重大创新(Project Loom)。它旨在解决平台线程创建和管理成本高昂的问题,从而实现极高并发量的轻量级线程。虚拟线程也是一种用户态线程,由JDK而非操作系统提供。

立即学习“Java免费学习笔记(深入)”;

Miller CSV TSV JSON 数据处理器
Miller CSV TSV JSON 数据处理器

Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。

下载
  • 调度模型: 虚拟线程采用M:N的调度模型。这意味着大量的虚拟线程(M)可以被调度到数量相对较少的平台线程(N)上运行。这些平台线程被称为“载体线程”(Carrier Threads)。
  • 工作原理: 当一个虚拟线程执行阻塞操作(如I/O等待)时,JDK的调度器会“卸载”该虚拟线程,并将其状态保存起来,然后将载体线程释放给其他虚拟线程使用。当阻塞操作完成时,虚拟线程会被“重新挂载”到可用的载体线程上继续执行。这个过程对应用程序是透明的。
  • 优势:
    • 极度轻量: 虚拟线程的内存占用极小,可以创建数百万个,远超平台线程的限制。
    • 高吞吐量: 通过M:N调度模型,虚拟线程能够高效地利用载体线程,尤其适合I/O密集型应用,显著提升并发吞吐量。
    • 编程模型不变: 虚拟线程保留了传统的“一个请求一个线程”的同步编程模型,开发者无需学习复杂的异步编程范式,即可享受高并发带来的好处。
    • 克服绿色线程局限: 与绿色线程不同,虚拟线程可以动态地在多个载体线程之间切换,这意味着即使一个虚拟线程阻塞,也不会影响其他虚拟线程的执行,并且能够充分利用多核处理器的并行能力。

线程类型对比总结

下表清晰地展示了Java中不同线程类型的关键特性和调度模型:

线程类型 描述 Java线程(M) : 操作系统线程(N)
平台线程 直接封装操作系统线程。 1:1
绿色线程 在单个操作系统线程上运行多个用户线程。 M:1
虚拟线程 在多个操作系统线程上运行多个虚拟线程。 M:N (M > N)

示例代码:创建和使用虚拟线程

在Java中创建和使用虚拟线程非常简单,与创建平台线程的API非常相似:

import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public class VirtualThreadExample {

    public static void main(String[] args) throws InterruptedException {
        System.out.println("Starting main thread...");

        // 方式一:使用Thread.ofVirtual()创建并启动一个虚拟线程
        Thread virtualThread1 = Thread.ofVirtual().name("my-virtual-thread-1").start(() -> {
            try {
                System.out.println(Thread.currentThread().getName() + " is running.");
                Thread.sleep(1000); // 模拟阻塞操作
                System.out.println(Thread.currentThread().getName() + " finished.");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        // 方式二:使用Executors创建虚拟线程池
        ThreadFactory virtualThreadFactory = Thread.ofVirtual().name("my-virtual-thread-", 0).factory();
        try (var executor = Executors.newThreadPerTaskExecutor(virtualThreadFactory)) {
            for (int i = 0; i < 5; i++) {
                final int taskId = i;
                executor.submit(() -> {
                    try {
                        System.out.println(Thread.currentThread().getName() + " - Task " + taskId + " is running.");
                        Thread.sleep(500 + taskId * 100); // 模拟不同时长的阻塞
                        System.out.println(Thread.currentThread().getName() + " - Task " + taskId + " finished.");
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                });
            }
        } // executor会自动关闭并等待所有任务完成

        virtualThread1.join(); // 等待第一个虚拟线程完成
        System.out.println("Main thread finished.");
    }
}

运行上述代码,你会发现尽管有多个虚拟线程在执行模拟阻塞操作,它们仍然能够高效地并发运行,并且输出的线程名会显示它们是虚拟线程。

注意事项与总结

  • 适用场景: 虚拟线程特别适合I/O密集型应用,如Web服务器、数据库连接池等,这些应用通常有大量的请求需要等待外部资源(网络、磁盘),但CPU计算量不大。
  • 不适用于CPU密集型: 对于CPU密集型任务,虚拟线程并不能提供额外的性能优势,因为它们最终仍然运行在有限的载体线程上。在这种情况下,平台线程可能更直接或需要结合响应式编程模型。
  • 监控与调试: 虚拟线程的引入对Java的监控和调试工具提出了新的挑战,但JDK和相关工具正在逐步完善对虚拟线程的支持。

虚拟线程是Java平台在并发领域的一次重大飞跃,它以轻量级、高吞吐量的特性,极大地简化了高并发应用的开发,同时保持了传统的编程模型。理解其与绿色线程和平台线程的区别,掌握其调度机制,是现代Java开发者必备的知识。

热门AI工具

更多
蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

LibLibAI
LibLibAI Hot

一款AI视频创作工具,主要用于国内领先的AI创意平台,以海量模型、低门槛操作与“创作-分享-商业化”生态,让小白与专业创作者都能高效实现图文乃至视频创意表达,适合需要提升相关任务效率的用户。

相关专题

更多
线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

3638

2023.08.10

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

2365

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

3681

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

2531

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

867

2023.09.05

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

2287

2023.10.09

数据库对象名无效怎么解决
数据库对象名无效怎么解决

数据库对象名无效解决办法:1、检查使用的对象名是否正确,确保没有拼写错误;2、检查数据库中是否已存在具有相同名称的对象,如果是,请更改对象名为一个不同的名称,然后重新创建;3、确保在连接数据库时使用了正确的用户名、密码和数据库名称;4、尝试重启数据库服务,然后再次尝试创建或使用对象;5、尝试更新驱动程序,然后再次尝试创建或使用对象。

2307

2023.10.16

vb连接access数据库的方法
vb连接access数据库的方法

vb连接access数据库方法:1、使用ADO连接,首先导入System.Data.OleDb模块,然后定义一个连接字符串,接着创建一个OleDbConnection对象并使用Open() 方法打开连接;2、使用DAO连接,首先导入 Microsoft.Jet.OLEDB模块,然后定义一个连接字符串,接着创建一个JetConnection对象并使用Open()方法打开连接即可。

2793

2023.10.16

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

0

2026.09.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn