首先了解一个理念:线程与 OS 线程 1:1 绑定

在传统 Java 线程(平台线程)模型中:

  1. 每个 Java 线程直接对应一个操作系统级别的线程

  2. 操作系统负责调度这些线程

  3. 线程的创建、管理和调度都由操作系统内核处理

  4. 这种模型称为 1:1 线程模型(一个用户线程对应一个内核线程)

图解传统线程模型

虚拟线程的 M:N 模型

什么是虚拟线程

1. 什么是虚拟线程?

        虚拟线程是一种轻量级的线程,由JVM管理,而不是操作系统。它们被设计用来显著减少编写、维护和观察高吞吐量并发应用程序的工作量。

        传统线程(平台线程):每个线程都直接对应一个操作系统线程(内核线程)。创建大量平台线程会消耗大量系统资源(内存和调度开销),因此限制了应用程序的并发能力。

        虚拟线程:它们是用户模式的线程,由JVM调度,多个虚拟线程可以运行在同一个平台线程(称为载体线程)上。虚拟线程的创建和切换成本极低,因此可以创建数百万个虚拟线程而不会导致系统资源耗尽。

2. 为什么需要虚拟线程?

        在传统的“一个请求一个线程”的服务器应用程序中,由于平台线程的资源限制,通常只能处理数千个并发连接。当有大量I/O等待时(如数据库调用、网络请求),线程被阻塞,导致资源浪费。

        虚拟线程通过以下方式解决

                高效阻塞:当虚拟线程执行阻塞操作(如I/O)时,它会自动从载体线程上卸载,从而释放载体线程去执行其他虚拟线程。当阻塞操作完成时,虚拟线程会被调度到某个载体线程上继续执行。

                高并发:可以创建大量虚拟线程(如百万级别),使得每个请求可以在自己的虚拟线程中运行,而无需复杂的异步编程模型(如CompletableFuture或反应式编程)。

Java 虚拟线程

前言

        虚拟线程(Virtual Threads)是 Java 并发模型的革命性创新,在 Java 19 作为预览特性引入,Java 21 正式发布。这是 Project Loom 的核心成果,旨在解决传统线程的瓶颈问题。


一、核心问题:传统线程的局限性

传统的Java线程

// 传统线程模型(平台线程)
ExecutorService executor = Executors.newFixedThreadPool(200);
for (int i = 0; i < 10_000; i++) {executor.submit(() -> {Thread.sleep(1000); // 模拟I/O阻塞return processRequest();});
}); }

痛点

  1. 线程与 OS 线程 1:1 绑定

  2. 创建 10k 线程 → 内存耗尽(1线程≈1MB栈)

  3. 上下文切换开销大(微秒级)

  4. 阻塞操作浪费 CPU 资源

一、如何创建虚拟线程

1. 直接创建

 // 1. 使用静态方法 `Thread.startVirtualThread(Runnable)Thread.startVirtualThread(new Runnable() {@Overridepublic void run() {System.out.println("Hello, Virtual Thread!");}});//2.(推荐使用)使用构建器模式 `Thread.ofVirtual().name("name").start(Runnable)// name方法// - 第一个参数 `"vt-"` 是名称前缀。//- 第二个参数 `1` 是起始序号。//- 实际生成的线程名称将是 `"vt-1"`、`"vt-2"`、`"vt-3"` 等,每次创建一个新线程时序号自动增加。Thread vt = Thread.ofVirtual().name("vt-", 1).start(() -> {System.out.println("Running in virtual thread");});
2. 线程池(推荐)
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {for (int i = 0; i < 100_000; i++) {executor.submit(() -> {// 处理请求(含I/O阻塞)return processRequest();});}
} // 自动关闭

核心区别对比表

特性传统线程(平台线程)虚拟线程
与OS关系1:1 绑定(直接对应OS线程)M:N 映射(JVM管理)
内存开销约 1MB/线程(默认栈大小)约 200B-2KB/线程
创建数量上限通常数千个数百万个
创建速度毫秒级(涉及OS调用)微秒级(纯JVM操作)
阻塞成本整个OS线程被阻塞仅虚拟线程暂停,载体线程释放
调度器操作系统内核JVM(用户态)
上下文切换内核介入,开销大(微秒级)JVM管理,开销极小(纳秒级)
典型使用场景new Thread() 或固定大小线程池Thread.ofVirtual().start() 或虚拟线程池

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89322.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89322.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/89322.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

掌握系统设计的精髓:12个核心设计模式的通俗解读

在构建复杂且高可用的软件系统时&#xff0c;仅仅了解编程语言和算法是不够的。真正的挑战在于如何设计出能够应对并发、故障、扩展等各种问题的健壮架构。系统设计模式正是前辈们在无数实践中提炼出的智慧结晶&#xff0c;它们是解决常见系统问题的“最佳实践”。 本文将深入浅…

概率论与数理统计(二)

事件的概率 概率&#xff1a;可能性的大小 古典概率模型&#xff1a; 1&#xff09;有限个样本点 2&#xff09;等可能性 P(A)A中包含的基本事件数基本事件总和 P(A) \frac{A中包含的基本事件数}{基本事件总和} P(A)基本事件总和A中包含的基本事件数​ 频率与概率 nnn 次实验…

新型eSIM攻击技术可克隆用户资料并劫持手机身份

eSIM技术存在重大安全漏洞研究人员发现eSIM技术中存在一个关键漏洞&#xff0c;攻击者可利用该漏洞克隆移动用户资料并劫持手机身份。AG安全研究团队宣布&#xff0c;他们成功攻破了采用GSMA消费者证书的Kigen eUICC&#xff08;嵌入式通用集成电路卡&#xff09;安全防护&…

langchain教程2:更加高级和灵活的Prompt模板

文章目录 prompt模板 对话Prompt模板 函数大师 使用jinja2与f-string实现提示词模板格式化 组合式提示词模板 prompt模板 from langchain.prompts import PromptTemplateprompt = PromptTemplate.from_template("你是一个{name},帮我起一个具有{country}特色的{gender}名…

UE5使用Motion Warping有什么用?

在 UE5 中&#xff0c;Motion Warping 是一套用于「动态调整根运动动画」的系统插件&#xff0c;它能让带有根运动&#xff08;Root Motion&#xff09;的动画根据游戏运行时的环境自动变形&#xff08;Warp&#xff09;&#xff0c;以更精准地贴合目标位置或目标方向&#xff…

类模版的相关案例

案例实现&#xff1a;实现一个通用的数组类&#xff0c;要求如下&#xff1a;可以对内置数据类型以及自定义数据类型的数据进行存储将数组中的数据存储到堆区构造函数中可以传入数组的容量提供对应的拷贝构造函数以及operator防止浅拷贝问题提供尾插法和尾删法对数组中的数据进…

服务器端安全检测与防御技术概述

一、服务器安全风险1.不必要的访问&#xff08;如只提供HTTP服务&#xff09;--应用识别控制2.公网发起IP或端口扫描、DDOS攻击等--防火墙3.漏洞攻击&#xff08;针对服务器操作系统等&#xff09;--IPS4.根据软件版本的已知漏洞进行攻击&#xff0c;口令暴力破解、获取用户权限…

前端性能与可靠性工程系列: 渲染、缓存与关键路径优化

前端性能与可靠性工程系列: 渲染、缓存与关键路径优化 第一部分:揭秘浏览器 - 关键渲染路径 (CRP) 关键渲染路径 (Critical Rendering Path - CRP) 是指浏览器从接收到最初的 HTML、CSS 和 JavaScript 字节,到最终将它们渲染成可见像素所必须经过的一系列步骤。我们的目标,…

基于CentOS的分布式GitLab+Jenkins+Docker架构:企业级CI/CD流水线实战全记录

引言&#xff1a;从单机到分布式容器架构的演进在传统Web应用部署中&#xff0c;我们常常面临环境不一致、部署效率低下等问题。我曾经维护过一个需要手动在5台服务器上重复部署的游戏项目&#xff0c;每次发布都如同走钢丝。本文将详细分享如何基于CentOS系统&#xff0c;构建…

JVM——为什么Java8移除了永久代(PermGen)并引入了元空间(Metaspace)?

Java8移除永久代并引入元空间&#xff0c;主要是为了解决 PermGen 固定大小、容易导致内存溢出、GC 效率低的问题。元空间使用本地内存&#xff0c;具备更灵活的内存分配能力&#xff0c;提升了垃圾收集和内存管理的效率。 PermGen 的局限性 ①固定大小:永久代的内存空间大小在…

3.正则化——新闻分类

影响结果出了最终的目标&#xff0c;还会有许多细节因素 在机器学习中&#xff0c;往往会面临很多过拟合和欠拟合的问题。 欠拟合是训练不到位&#xff0c;过拟合是训练过头&#xff0c;会导致泛化性差正则化是在损失函数中添加一个惩罚项&#xff0c;以简化模型对于惩罚项Pena…

HTML的重要知识

什么是HTMLHTML是Hyper Text Markup Language的缩写&#xff0c;意思是超文本标记语言。标签标题标签&#xff1a;————-h1,h2,h3.....段落标签 &#xff1a;————p换行标签&#xff1a; ————br列表标签&#xff1a;有序列表&#xff1a;——ol无序列表&#xff1a;—…

【C语言网络编程】HTTP 客户端请求(发送请求报文过程)

在 C 语言中&#xff0c;我们可以使用 socket 编程来手动实现一个简单的 HTTP 客户端&#xff0c;像浏览器一样请求网页数据。本文将结合实际代码&#xff0c;重点讲解如何通过 C 语言构造并发送一个 HTTP 请求报文&#xff0c;实现与服务器的基本通信。 文章目标 通过一个简单…

oracle2kingbase的字段长度问题

实验一&#xff1a; oracle中&#xff1a; create table testlen(c1 varchar2(2)); insert into testlen values(山); --成功 insert into testlen values(山西); --失败 ORA-12899: 列 "TESTK"."TESTLEN"."C1" 的值太大 (实际值: 4, 最大值: 2…

单链表的题目,咕咕咕

1.咕 203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 struct ListNode* removeElements(struct ListNode* head, int val) …

关于程序=数据结构+算法这句话最近的一些思考

最近看了很多单片机STM32的的相关程序&#xff0c;尤其是设计到ringbuff、buffer_manage、os_memory预计mem_manage等程序中间层的用法&#xff0c;我对这句话有了一些更深的思考&#xff0c;现在记录下来&#xff0c;希望对处于相同阶段的程序一些思想启迪。首先“数据结构”也…

Rust 错误处理

Rust 错误处理 引言 Rust 是一种系统编程语言&#xff0c;以其安全、并发和性能著称。在 Rust 中&#xff0c;错误处理是一个核心概念&#xff0c;它确保了程序在遇到异常情况时能够优雅地处理。本文将深入探讨 Rust 中的错误处理机制&#xff0c;包括错误类型、错误传播、错误…

17. 什么是 webSocket ?

总结 WebSocket 是 HTML5 引入的一种新协议&#xff0c;允许客户端和服务器之间进行双向实时通信。建立在 TCP 协议之上&#xff0c;默认端口是 80&#xff08;ws&#xff09; 和 443&#xff08;wss&#xff09;&#xff0c;没有同源限制&#xff0c;客户端可以与任意服务器通…

从零开始跑通3DGS教程:(五)3DGS训练

写在前面 本文内容 所属《从零开始跑通3DGS教程》系列文章; 本文介绍在docker中训练3dgs的方法 平台/环境 linux, nvidia GPU, docker 转载请注明出处: https://blog.csdn.net/qq_41102371/article/details/146535874 目录 写在前面系列文章准备docker创建环境参考完系列文章…

日记_7.14_实际开发的进步

1、快速定位后端2、会定位前端啦啦啦&#xff01;3、前端没有意义的块叫div和span。而不是script4、所有 JavaScript 标识符均 区分大小写5、JS中$和_下划线和doller符均被视为字母。6、var、let区别&#xff1a;1 var全局。let局部。2 var可以重新声明格式&#xff0c;let之恩…