线程 vs 虚拟线程:深入理解及区别
Java 提供了两种线程机制:普通线程(平台线程)和 虚拟线程。普通线程是 Java 中经典的并发处理方式,而虚拟线程是随着 Java 21 引入的新特性,旨在提升并发性能和开发体验。本文将详细探讨它们的区别,并帮助你理解如何在实际开发中利用这些机制。
一、什么是线程?
在计算机科学中,线程是程序执行的最小单位。每个线程有自己独立的栈和程序计数器,能够独立执行代码。Java 提供了多线程机制,使得多个线程可以并发地执行任务,提高程序的响应速度和处理能力。
普通线程,也称为平台线程,是直接映射到操作系统的内核线程。每个线程都有自己独立的资源(栈、寄存器等),并且受限于操作系统对线程的管理与调度。
二、普通线程的特点
-
重量级线程:普通线程直接与操作系统线程绑定,因此是“重量级”线程。创建、销毁线程需要操作系统分配资源,导致其成本较高。
-
并发调度:操作系统负责对所有普通线程进行调度,这意味着线程数的增加会给系统带来额外的上下文切换开销,导致性能下降。
-
阻塞问题:由于普通线程直接与操作系统内核线程绑定,任何阻塞操作(如 I/O 操作)会导致线程被挂起,从而降低系统整体的吞吐量。
-
线程池的使用:由于普通线程的高创建成本,开发者通常会使用线程池来管理线程,以避免频繁创建和销毁线程带来的性能开销。
ExecutorService executor = Executors.newFixedThreadPool(10); for (int i = 0; i < 100; i++) {executor.submit(() -> {System.out.println("Running task");}); } executor.shutdown();
三、虚拟线程的引入
随着并发应用需求的增长,Java 在 JDK 21 中引入了虚拟线程(Virtual Threads),也称为轻量级线程。虚拟线程旨在解决普通线程存在的开销高、并发受限的问题,从而简化高并发场景下的编程模式。
虚拟线程本质上是一个用户级线程,独立于操作系统的线程调度。虚拟线程由 Java 虚拟机(JVM)管理,创建和销毁的开销非常小,能够并行执行数百万个线程。
四、虚拟线程的特点
-
轻量级线程:虚拟线程是“轻量级”的,创建、销毁和切换的成本非常低,允许开发者轻松创建数百万个虚拟线程。相比之下,普通线程的数量受限于操作系统资源。
-
非阻塞模型:虚拟线程能够非阻塞地处理任务,即使线程被阻塞,JVM 也可以在另一个内核线程上继续调度其他虚拟线程,从而最大化 CPU 利用率。
Thread.startVirtualThread(() -> {// 虚拟线程中的任务System.out.println("Running in a virtual thread"); });
-
资源节约:由于虚拟线程使用的资源较少,它们可以显著减少内存和 CPU 的消耗,特别是在高并发的 I/O 密集型任务中表现出色。
-
可伸缩性:虚拟线程非常适合处理大量短时间运行的任务,这使得它们在高并发系统中具有更好的扩展性和可伸缩性。
-
自动调度:JVM 会自动调度虚拟线程到内核线程上,开发者不再需要手动配置线程池,这极大地简化了多线程编程。
虚拟线程的出现将 Java 线程模型的设计思路从原来的“少而精”变为“多而轻”,使得每个任务都可以拥有自己的独立线程,而无需考虑线程资源的限制。
五、普通线程与虚拟线程的区别
特性 | 普通线程 | 虚拟线程 |
---|---|---|
创建成本 | 高,需要操作系统分配内核资源 | 低,由 JVM 轻量管理 |
数量限制 | 受限于操作系统资源 | 可以创建数百万个虚拟线程 |
阻塞行为 | 阻塞会占用操作系统线程 | 阻塞时,JVM 自动调度其他任务 |
上下文切换成本 | 高,涉及内核态和用户态切换 | 低,全部在用户态完成 |
适用场景 | 适合长时间运行的任务 | 适合高并发的短期任务 |
资源消耗 | 需要大量的内存和 CPU 资源 | 极大节省资源,尤其是在 I/O 密集型任务中 |
调度机制 | 由操作系统调度 | 由 JVM 管理和调度 |
六、使用虚拟线程的实际案例
在实际应用中,虚拟线程特别适合需要处理大量 I/O 操作的高并发场景。比如处理高并发 HTTP 请求,传统的线程池模型可能需要精心设计,而使用虚拟线程,开发者可以轻松启动数十万甚至数百万个线程来处理每个请求。
try (var server = HttpServer.create()) {server.createContext("/echo", exchange -> {var body = exchange.getRequestBody().readAllBytes();exchange.sendResponseHeaders(200, body.length);exchange.getResponseBody().write(body);});server.start();
}
在这个例子中,服务器为每个请求启动一个虚拟线程,从而消除了线程池的复杂性。
七、虚拟线程的优势与挑战
优势:
- 简化并发编程:虚拟线程消除了开发者对线程池的依赖,能够以同步的方式编写代码,而不牺牲性能。
- 更高的并发能力:虚拟线程允许更高数量的并发处理,尤其适用于 I/O 密集型任务。
- 更低的系统资源占用:相比普通线程,虚拟线程占用的内存和 CPU 资源极少,可以在资源受限的环境中运行。
挑战:
- 生态系统支持:虽然 Java 已经开始引入虚拟线程,但一些现有的 Java 框架和库可能还需要一段时间才能完全兼容虚拟线程。
- 性能调优:尽管虚拟线程减少了创建和切换线程的开销,但在高密集 CPU 任务场景下,虚拟线程的调度仍然需要谨慎调优。
八、总结
虚拟线程的引入为 Java 开发带来了革命性的变化,特别是在高并发和 I/O 密集型场景中。与传统的普通线程相比,虚拟线程提供了更低的创建成本、更高的可伸缩性,并且简化了多线程编程模式。
在实际项目中,开发者可以根据任务的复杂性和并发需求,灵活选择使用普通线程还是虚拟线程。普通线程仍然适用于长时间运行的 CPU 密集型任务,而虚拟线程则是处理高并发、短期任务的最佳选择。随着 Java 虚拟线程的成熟,未来多线程编程将变得更加简洁、高效。
相关文章:

线程 vs 虚拟线程:深入理解及区别
Java 提供了两种线程机制:普通线程(平台线程)和 虚拟线程。普通线程是 Java 中经典的并发处理方式,而虚拟线程是随着 Java 21 引入的新特性,旨在提升并发性能和开发体验。本文将详细探讨它们的区别,并帮助你…...

【WEB应用安全测试指南–蓝队安全测试2】--超详细-可直接进行实战!!!亲测-可进行安全及渗透测试
安全基础理论入门知识参考上一篇《WEB应用安全测试指南蓝队安全测试1》 WEB应用安全测试指南2 一、文件 I/O 类1.1、任意文件上传1.2、任意文件下载1.3、文件包含 二、接口安全类2.1、短信炸弹2.2、邮件炸弹2.3、短信内容可控2.4、邮件内容可控 三、逻辑流程类3.1、越权3.2、未…...

使用HTML、CSS和JavaScript创建滚动弹幕效果
使用HTML、CSS和JavaScript创建滚动弹幕效果 在现代网页设计中,滚动文本是一种常见的动态效果,可以吸引用户的注意力并增强交互体验。在这篇博客文章中,我们将详细介绍如何使用HTML、CSS和JavaScript实现滚动文本效果。 效果 步骤1…...

【C语言】--数组
😊个人主页: 起名字真南 😋个人专栏:【数据结构初阶】 【C语言】 【C】 目录 1 数组的概念2 一维数组的创建和初始化2.2 数组的初始化2.3 数组类型 3 一维数组的使用3.1 数组下标3.2 数组的输入 4 一维数组在内存中的存储5 sizeof计算数组中的元素6 二维…...

面向B2B市场的Spring Boot医疗病历系统开发
第1章绪论 计算机已经从科研院所,大中型企业,走进了平常百姓家,Internet遍及世界各地,在网上能够用计算机进行文字草拟、修改、打印清样、文件登陆、检索、综合统计、分类、数据库管理等,用科学的方法将无序的信息进行…...

闭着眼学机器学习——支持向量机分类
引言: 在正文开始之前,首先给大家介绍一个不错的人工智能学习教程:https://www.captainbed.cn/bbs。其中包含了机器学习、深度学习、强化学习等系列教程,感兴趣的读者可以自行查阅。 1. 算法介绍 支持向量机(Support Vector Mach…...

今日指数项目day8实战权限管理器(上)
3.权限管理器 3.1 权限列表展示功能 1)原型效果 2)接口说明 功能描述: 查询所有权限集合 服务路径: /api/permissions 服务方法:Get 请求参数:无响应数据格式: {"code": 1,"data":…...

《机器学习与数据挖掘综合实践》实训课程教学解决方案
一、引言 随着信息技术的飞速发展,人工智能已成为推动社会进步的重要力量。作为人工智能的核心技术之一,机器学习与数据挖掘在各行各业的应用日益广泛。本方案旨在通过系统的理论教学、丰富的实践案例和先进的实训平台,帮助学生掌握机器学习…...

linux中软连接和硬链接的区别
定义与概念 硬链接(Hard Link):硬链接是文件系统中的一个概念,它直接指向文件系统中的物理数据块。可以把硬链接看作是原始文件的一个别名,它们共享相同的inode(索引节点)编号。在Linux文件系统…...

#Swift 对比 Static 在Swift 和 OC中的用法
在 Objective-C 和 Swift 中,static 关键字都用于定义类型级别的成员,但它们的用法和行为在两个语言中有所不同。让我们来详细对比一下 Objective-C 和 Swift 中 static 的使用方式和特性。 1. Objective-C 中的 static 在 Objective-C 中,…...

yakit使用教程(三,端口探测和指纹扫描)
本文仅作为学习参考使用,本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 前言: 前文链接:yakit下载安装教程。 1.端口扫描的作用。 对目标端口进行扫描可以知道目标服务器开启了什么服务,以便于针对其所存在的服务展开…...

一维数组的引用
#define SIZE 5 int main(void) { int i 0; int arr[SIZE] { 86,85,85,896,45 };//同理五个数据只是偶然,可能会更多 //输入 for (i 0;i < SIZE;i) { printf("请输入你的第%d个值:",i1); scanf_s(&…...

Vue3 watch 监视属性
作用:监视数据的变化(和Vue2中的watch作用一致)特点:Vue3中的watch只能监视以下四种数据: ref定义的数据。reactive定义的数据。函数返回一个值(getter函数)。一个包含上述内容的数组。 我们在V…...

大数据-158 Apache Kylin 安装配置详解 集群模式启动
点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…...

PHP商会招商项目系统一站式服务助力企业腾飞
商会招商项目系统——一站式服务,助力企业腾飞 🚀💼 🚀 开篇:企业成长的加速器,商会招商项目系统来袭 在竞争激烈的市场环境中,企业如何快速找到适合自己的发展路径,实现腾飞&…...

pnpm 和 npm
pnpm 和 npm 是 JavaScript 生态系统中常用的包管理工具,它们各自有不同的特性和优缺点。下面是这两者的详细比较: 1. 基本概念 npm (Node Package Manager): 是 Node.js 的默认包管理器,提供安装、更新、卸载 JavaScript 包的功…...

笔试算法总结
文章目录 题目1题目2题目3题目4 题目1 使用 StringBuilder 模拟栈的行为,通过判断相邻2个字符是否相同,如果相同就进行删除 public class Main {public static String fun(String s) {if (s null || s.length() < 1) return s;StringBuilder builde…...

mybatisPlus对于pgSQL中UUID和UUID[]类型的交互
在PGSQL中,有的类型是UUID和UUID[]这种类型,在mybatis和这些类型交互的时候需要手动设置类型处理器才可以,这里记录一下类型处理器的设置 /*** UUID类型处理器*/ public class UUIDTypeHandler extends BaseTypeHandler<UUID> {/*** 获…...

vue3 高德地图标注(飞线,呼吸点)效果
装下这两个 npm 忘了具体命令了,百度一下就行 “loca”: “^1.0.1”, “amap/amap-jsapi-loader”: “^1.0.1”, <template><div id"map" style"width: 100%;height: 100%;"></div> </template><script setup> …...

程序员成长秘籍:是迈向管理巅峰,还是深耕技术架构?
专业在线打字练习平台-巧手打字通,只输出有价值的知识。 一 管理和架构 做技术的同学一般有两条职业发展路径,横向的管理路线和纵向的技术路线。管理路线对应的是管理岗,讲究的是排兵布阵,通过各种资源的优化配置发挥价值。技术路…...

xargs的参数及常用命令
1. xargs 命令简介 xargs 是一个非常有用的工具,它用于从标准输入(stdin)构建和执行命令行。xargs 可以将标准输入中以空格或换行符分隔的数据,转化为命令的参数传递给其他命令。 使用场景: 当某些命令不支持使用管…...

FLASK 数据库建立以及部署和表的创建
首先安装flask-sqlalchemy db SQLAlchemy(app) 一 Mmeber、User模型类的创建 # coding: utf-8 from app import db, appclass Member(db.Model):__tablename__ memberid db.Column(db.Integer, primary_keyTrue)membername db.Column(db.String(100), uniqueTrue, index…...

微信小程序的面试题
简述下 wx.navigateTo(), wx.redirectTo(), wx.switchTab(), wx.navigateBack(), wx.reLaunch() 区别 ? wx.navigateTo() : 保留当前页面,跳转到应用内的某个页面。但是不能跳到 tabbar 页面 wx.redirectTo() : 关闭当前页面,跳转到应用内的…...

udp c语言实现组播的例子
一、组播与广播的区别 1、组播地址和广播地址是不同的概念 组播地址:用于将数据包发送到一组特定的接收者,只有加入该组播地址的设备才能接收数据。它提高了网络效率,因为发送者只需发送一份数据。 广播地址:用于将数据包发送到…...

ffmpeg面向对象——AVInputFormat与URLProtocol啥关系
《ffmpeg面向对象-rtsp拉流相关对象》和《ffmpeg面向对象——拉流协议匹配机制探索》探索过了输入格式匹配和底层协议匹配,且ffmpeg拉流是先是匹配输入格式——抽象为AVInputFormat类,然后再匹配url协议类——抽象为URLProtocol类。 它们是啥关系&#…...

【高阶数据结构】二叉树进阶探秘:AVL树的平衡机制与实现详解
高阶数据结构相关知识点可以通过点击以下链接进行学习一起加油!二叉搜索树 大家好,这里是店小二!今天我们将深入探讨高阶数据结构中的AVL树。AVL树是一种自平衡的二叉搜索树,可以看作是对传统二叉搜索树的优化版本。如果你对数据结…...

中级软考软件设计师真题+模拟题+课件讲解+机考讲解模拟+笔记分享
软考真题分享 下载链接⬇️⬇️: 下载链接...

MySQL—视图
前言: 视图是一个虚拟的表,是基于一个或多个基本表或其他视图的查询结果集。视图本身不占据物理储存空间,仅仅只是一个查询的逻辑表示,物理上依赖于数据表的数据。 视图具有简单,安全,逻辑数据独立&#…...

鸿蒙OS启动流程
启动流程(基于openharmony4.1) 系统上电加载内核后,按照以下流程完成系统各个服务和应用的启动: 内核加载init进程,一般在bootloader启动内核时通过设置内核的cmdline来指定init的位置。init进程启动后,会挂载tmpfs,…...

服务器数据恢复—EMC存储RAID5磁盘阵列数据恢复案例
服务器数据恢复环境: 一台EMC某型号存储设备,该存储中有一组由12块(包括2块热备盘)STAT硬盘组建的raid5阵列。 服务器故障: 该存储在运行过程中突然崩溃,raid瘫痪。数据恢复工程师到达现场对故障存储设备进…...