首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏王磊的博客

    面试官:什么是虚拟线程?为什么要有虚拟线程

    Java 中的虚拟线程,也叫做协程或“轻量级线程”,它诞生于 JDK 19(预览 API),正式发布于 JDK 21,它是一种在 Java 虚拟机(JVM)层面实现的逻辑线程,不直接和操作系统的物理线程一一对应 操作系统线程、普通线程(Java 线程)和虚拟线程的关系如下:虚拟线程使用虚拟线程的创建方式,主要有以下 4 种:Thread.startVirtualThread(Runnable task)Thread.ofVirtual (()->{ System.out.println("Do virtual thread.");});// 运行虚拟线程vt.start();3.factory先创建虚拟线程工厂,然后再使用工厂创建虚拟线程 普通线程默认创建的是用户线程(而守护线程),而虚拟线程是守护线程,并且其守护线程的属性不能被修改,如果修改就会报错,如下图所示:虚拟线程由 JVM 调度和使用,避免了普通线程频繁切换的性能开销,所以相比于普通的线程来说 小结线程是轻量级的进程,而虚拟线程则是轻量级的线程虚拟线程是 JVM 层面实现的逻辑线程,不直接和操作系统的物理线程一一对应,因此使用它可以减少线程上下文切换所带来的性能开销。

    1.1K10编辑于 2023-12-20
  • 来自专栏技术分享

    JDK23--虚拟线程

    Java23下载地址:https://www.oracle.com/cn/java/technologies/downloads/虚拟线程的特点 轻量级每个虚拟线程的创建和销毁成本非常低,可与协程的成本相媲美 阻塞与非阻塞兼容 虚拟线程支持阻塞式代码风格,即便线程处于阻塞状态,也不会浪费操作系统资源,因为虚拟线程在阻塞时会自动挂起并释放底层资源。同时兼容现有的非阻塞 I/O,开发者无需改变已有的代码习惯。 透明性 使用虚拟线程无需学习新的 API,开发者可以像使用传统线程一样简单地操作虚拟线程。 每个虚拟线程可以由一个或多个操作系统线程动态映射和执行,从而提升资源利用率。虚拟线程的应用场景 高并发网络应用 适用于需要处理大量用户请求的服务器,例如 Web 服务、聊天系统等。 如何使用虚拟线程从 JDK 19 开始,虚拟线程作为预览特性引入,JDK 21 及之后版本正式稳定。

    53620编辑于 2025-01-10
  • 来自专栏FunTester

    Spring WebClient + 虚拟线程实战

    Spring WebClient 与虚拟线程:实战集成指南 在上一篇文章中,我们介绍了 JDK HttpClient 和虚拟线程的基础概念。 与 Spring WebClient 集成 你也可以增强 Spring WebClient,使其使用虚拟线程,将 Spring 强大的生态系统与虚拟线程的可扩展性结合起来。 这样你既能享受 Spring 的便利,又能获得虚拟线程的性能优势。 虚拟线程消除了简单性(每个请求一个线程)与可扩展性之间的传统权衡。 虚拟线程使这种模式高效且简单。

    23910编辑于 2025-12-21
  • 来自专栏猫头虎博客专区

    虚拟线程(Virtual Threads):什么是JDK 21中的虚拟线程?如何实现轻量级线程管理?

    虚拟线程(Virtual Threads):什么是JDK 21中的虚拟线程?如何实现轻量级线程管理? 引言 在Java中,传统线程由操作系统管理,虽然功能强大,但开销较大,无法高效处理海量并发任务。 核心概念:什么是虚拟线程? 1. 定义与特性 虚拟线程(Virtual Threads) 是一种由JVM而非操作系统直接管理的线程。 启用虚拟线程的环境要求 虚拟线程是JDK 21正式发布的新特性,确保以下环境支持: JDK 21及以上版本。 --enable-preview 标志以启用虚拟线程。 2. 阻塞操作:避免在虚拟线程中执行耗时的阻塞操作,如锁或长时间计算。 Q&A互动答疑 Q:虚拟线程可以完全替代传统线程吗? A:虚拟线程适合高并发任务,但在一些场景(如与本地代码交互、计算密集型任务)仍需使用传统线程。 Q:虚拟线程是否线程安全?

    2.4K11编辑于 2024-12-20
  • 来自专栏我是业余自学C/C++的

    8.线程

    线程 进程:使多个程序能并发执行,以提高资源利用率和系统吞吐量。 引入线程,是为了救减少程序在并发执行时所付出的时空开销,使OS具有更好的并发性。 引入线程的目的 进程是可拥有资源的独立单位和可独立调度和分派的基本单位。 创建、撤销和切中,系统必须为之付出较大的时空开销。故进程,其数目不宜过多,进程切换的频率也不宜过高。 线程的属性 (1)轻型实体。线程中的实体基本上不拥有系统资源。 (2)独立调度和分派的基本单位。线程的切换非常迅速、开销小。 (3)可并发执行。 (4)共享进程资源。

    37830发布于 2019-03-12
  • 来自专栏得物技术

    虚拟线程原理及性能分析

    CompletableFuture 是由 Java8 引入的,在 Java8 之前一般通过 Future 实现异步。 Future 用于表示异步计算的结果,如果存在流程之间的依赖关系,那么只能通过阻塞或者轮询的方式获取结果,同时原生的 Future 不支持设置回调方法,Java8 之前若要设置回调可以使用 Guava 载体线程(Carrier Thread):指真正负责执行虚拟线程中任务的平台线程。一个虚拟线程装载到一个平台线程之后,那么这个平台线程就被称为虚拟线程的载体线程。 444https://zhuanlan.zhihu.com/p/514719325https://www.vlts.cn/post/virtual-thread-source-code#%E5%89%8D %E6%8F%90https://zhuanlan.zhihu.com/p/499342616*文/creed本文属得物技术原创,更多精彩文章请看:得物技术官网未经得物技术许可严禁转载,否则依法追究法律责任

    1.8K41编辑于 2023-12-06
  • 来自专栏芋道源码

    SpringBoot 物理线程虚拟线程、Webflux 性能全面对比!

    介绍 在本文中,我们将深入探讨所有同级产品之间的友好比较,即具有「物理线程虚拟线程和 Webflux 的 SpringBoot」 ,重点关注它们在特定用例场景中的性能。 —它在虚拟线程而不是传统的物理线程上运行。 虚拟线程是并发领域的游戏规则改变者。这些轻量级线程简化了开发、维护和调试高吞吐量并发应用程序的复杂任务。 虽然虚拟线程仍然在底层操作系统线程上运行,但它们带来了显着的效率改进。 当虚拟线程遇到阻塞 I/O 操作时,Java 运行时会暂时挂起它,从而释放关联的操作系统线程来为其他虚拟线程提供服务。这个优雅的解决方案优化了资源分配并增强了整体应用程序响应能力。 、虚拟线程和 Webflux 进行友好性能评估的背景下,了解关键的数据关系至关重要。

    97000编辑于 2025-05-10
  • 来自专栏痴者工良

    C#多线程(8):线程完成数

    也就是说,设定一个计数器,每个线程完成后,就会减去 1 ,当计数器为 0 时,代表所有线程都已经完成了任务。 Wait() 阻止当前线程,直到设置了 CountdownEvent 为止。 .Wait(); 用在一个线程中,这个线程将等待其它完成都完成任务后,才能继续往下执行。 Signal(); 用于工作线程中,向 CountdownEvent 对象发送信号,告知线程已经完成任务,然后 CountdownEvent.CurrentCount 将减去 1。 当计数器为 0 时,阻塞的线程将恢复执行。

    70430发布于 2021-04-26
  • 来自专栏∑小熊猫的博客

    Java 多线程系列(8) —— 线程同步基础

    线程同步基础 Synchronized Synchronized 关键字提供了一种锁机制,可以实现一个简单的策略来防止线程的干扰和内存一致性错误。 ,那么会造成数据读取的错误 内存可见性 在线程写入一个数据时,会先向缓存中写入数据,稍后在写入到本地的主存中去。 这就造成了一个线程写完了,另一个线程立刻去读取写入的数据,却读取到原先的值,虽然过一段时间后,可以读到这个数据,但是却是最终一致性,而不是强一致性。 使用 volatile 后,则会立刻写入到主存中去,对其他线程可见。 但是在多线程情况下便不能保证 as-if-serial 语义。 由于线程之间数据的依赖和相互影响,我们需要告知编译器和 CPU 在什么场景下可以进行重排序,什么时候不可以进行重排序。

    43410编辑于 2022-09-26
  • 来自专栏指点的专栏

    Java 多线程8)---- 线程组和 ThreadLocal

    线程组 ThreadGroup 我们前面已经讲了线程池,并且我们知道线程池是为了在子线程中处理大量的任务,同时又避免频繁的创建和销毁线程带来的系统资源开销而产生的。 那么线程组呢? 线程组可以说是为了方便和统一多个线程的管理而产生的。我们知道,在一个 Java 程序运行的时候会默认创建一个线程,我们称其为主线程,即为执行 main 方法的线程。 () // 清除当前线程组和其子线程组,需要保证当前线程组和其子线程组中的所有线程都已经停止了 void destroy​() // 将当前线程组和其子线程组中的线程拷贝到参数指定的线程数组中 , // 如果线程数组的长度小于线程组中线程的数量,那么多余的线程不会拷贝 int enumerate​(Thread[] list) // 将当前线程组中的线程拷贝到参数指定的线程数组中,如果 / 线程组之后,如果你没有给这个新建的线程 / 线程组指定一个父线程组,那么其默认会将当前执行创建线程 / 线程组代码的线程所属的父线程组作为新的线程 / 线程组的父线程组。

    68030发布于 2019-01-18
  • 来自专栏实战docker

    支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程

    :体验 支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用 本篇概览 本篇是《支持JDK19虚拟线程的web框架》系列的第三篇,在前面两篇咱们一起了解和体验了支持虚拟线程的 web服务,功能性能都试过,整个开发过程也完整执行,算是对quarkus和虚拟线程有了初步的了解,但也留下两个问题 虚拟线程和常规子线程的区别,究竟能不能看出来? 不使用虚拟线程时的线程状况 咱们先发请求到/pool/persons,也就是先不用虚拟线程,看看传统线程池响应web服务的时候,在JProfiler中是啥样的 像《上篇》那样,用K6压测接口/pool 相信您已经很清楚了吧,我觉得是这三样: 调度器,scheduler(ForkJoin线程池中的线程) 执行虚拟线程任务的真实线程,carrier 虚拟线程 现在开始压测吧,继续用k6,如下图,脚本中的地址要改成使用虚拟线程的 来完成虚拟线程中的任务,等到这些任务执行完毕,所有真实线程虚拟线程都被结束,不再存活 至此,借助JProfiler观察常规线程虚拟线程的实战就完成了,经过了这些理论结合实际的操作和分析,相信您对虚拟线程的认知已经更具体和全面

    84140编辑于 2022-11-03
  • 来自专栏架构师成长之路

    java(8)--线程ThreadLocal详解

    ThreadLocal与线程池 ThreadLocal与线程对象紧密绑定的, 一般web容器(如tomcat)使用了线程池,线程池中的线程是可能存在复用的。 这样,线程池中的线程在下一次请求被执行的时候,ThreadLocal对象的get()方法返回的将不是当前线程中设定的变量,因为池中的“子线程”根本不是当前线程创建的,当前线程设定的ThreadLocal 变量也就无法传递给线程池中的线程。 如果在子线程的生命周期内,父线程修改了自己的线程局部变量值,子线程再次读取,获取的仍然是第一次读取的值。即:子线程继承父线程的值,只是在线程创建的时候继承一次。之后子线程与后父线程便相互独 八. 线程池的父子线程传递InheritableThreadLocal 我们在使用线程的时候往往不会只是简单的new Thrad对象,而是使用线程池,线程池的特点: 1)为了减小创建线程的开销,线程池会缓存已经使用过的线程

    8.5K20编辑于 2022-04-14
  • 来自专栏架构狂人

    一文讲透虚拟线程

    虚拟线程和普通线程的区别 “虚拟线程,望文生义,它是“假”的,它不直接调度操作系统的线程,而是由 JVM 再提供一层线程的接口抽象,由普通线程调度,即一个普通的操作系统线程可以调度成千上万个虚拟线程虚拟线程比普通线程的消耗要小得多得多,在内存足够的情况下,我们甚至可以创建上百万的虚拟线程,这在之前(Java19 以前)是不可能的。 SpringBoot 使用虚拟线程 下面我们会在 SpringBoot 中使用虚拟线程,将默认的异步线程池和 http 处理线程池替换为虚拟线程,然后对比虚拟线程和普通线程的性能差异,你会发现差别就像马车换高铁 下面再看下虚拟线程的表现: 「虚拟线程耗时」: 可以看到即使是最大耗时,也保持在 100ms 以下,即线程等待时间显著的减少,虚拟线程更好的利用了系统资源。 最后:大部分的公司可能还在用 Java8,但是我想说的是,是时候升级了,跟上时代的脚步吧,朋友们!

    1.1K10编辑于 2024-07-16
  • 网易面试:SpringBoot如何开启虚拟线程

    虚拟线程是一种在 Java 虚拟机(JVM)层面实现的逻辑线程,不直接和操作系统的物理线程一一对应,因此它可以减少上下文切换所带来的性能开销。 操作系统线程、普通线程(Java 线程)和虚拟线程的关系如下:1.虚拟线程使用虚拟线程的创建有以下 4 种方式:Thread.startVirtualThread(Runnable task)Thread.ofVirtual 普通线程默认创建的是用户线程(而守护线程),而虚拟线程是守护线程,并且其守护线程的属性不能被修改,如果修改就会报错,如下图所示:虚拟线程由 JVM 调度和使用,避免了普通线程频繁切换的性能开销,所以相比于普通的线程来说 PS:这里是虚拟线程执行器,不是虚拟线程池。 有了虚拟线程后还需要虚拟线程池吗?为什么?

    2K10编辑于 2024-06-12
  • 来自专栏朱永胜的私房菜

    JDK21更新内容:虚拟线程

    Virtual Threads(虚拟线程)是Java平台的一项新功能,它旨在改进Java中的并发编程模型。传统上,Java使用基于操作系统线程的并发模型,每个线程都需要分配一个操作系统线程来执行。 具体而言,当一个Java应用程序创建一个Virtual Thread时,JVM会为其分配一个虚拟线程(也称为轻量级线程)。这些虚拟线程由协作调度器管理,并在需要时与操作系统线程进行绑定。 协作调度器负责决定哪个虚拟线程可以运行以及何时切换虚拟线程。 Fork/Join框架是Virtual Threads的另一个关键组件。 然后,我们通过调用execute()方法提交了一系列任务,每个任务都会打印当前运行的虚拟线程的名称。 7. 8. 总结 Virtual Threads是Java平台的一项新功能,旨在改进Java中的并发编程模型。它通过引入轻量级的虚拟线程,并利用协作调度器和Fork/Join框架来提供高效的并发执行。

    1.2K70编辑于 2023-09-25
  • 来自专栏FunTester

    JDK HttpClient 与虚拟线程入门指南

    简单来说,以前你要么写复杂的异步代码,要么忍受线程资源限制,现在虚拟线程让你鱼和熊掌兼得。 这就像传统线程是雇佣全职员工,成本高;虚拟线程是雇佣临时工,按需分配,成本低。 当将 JDK HttpClient 与虚拟线程集成时,魔法就发生了。 我们做了个基准测试,对 10,000 个并发 HTTP 请求进行测试,结果如下: • 传统平台线程8-10 秒,2-3 GB 内存(资源消耗大,速度慢) • 响应式 WebFlux:3-4 秒,500 MB 内存(性能好,但代码复杂) • 虚拟线程 + HttpClient:3-4 秒,300 MB 内存(性能好,代码简单) 虚拟线程实现了响应式级别的性能,同时代码更易于阅读且是命令式的。

    24710编辑于 2025-12-21
  • 来自专栏wayn的程序开发

    2 分钟理解虚拟线程是什么

    (大家为了节约线程资源,也就有了线程池的概念) 什么是虚拟线程? 与平台线程一样,虚拟线程也是 java.lang.Thread 的一个实例对象。但是,虚拟线程并不依赖于特定的操作系统线程虚拟线程底层仍然在操作系统的线程上运行代码。 而在虚拟线程中调用阻塞 I/O 操作时,JVM 虽然也会挂起该虚拟线程,但是与平台线程不同的是,被挂起虚拟线程关联的操作系统线程是可以为其他虚拟线程继续服务的。 虚拟线程的实现方式与虚拟内存类似。 因此与平台线程消耗的资源很多不同,虚拟线程在使用时只需要很少的内存资源。单个 JVM 就可以轻松创建数百万个虚拟线程。 尽管虚拟线程支持线程局部变量和可继承的线程局部变量,但我们应该仔细考虑后再使用它们,因为单个 JVM 可能运行数百万个虚拟线程

    44300编辑于 2023-12-29
  • 来自专栏实战docker

    支持JDK19虚拟线程的web框架,之四:看源码,了解quarkus如何支持虚拟线程

    :体验 支持JDK19虚拟线程的web框架,之二:完整开发一个支持虚拟线程的quarkus应用 支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程 本篇概览 本篇是《支持JDK19虚拟线程的 另外请放心,虽然quarkus源码复杂,但本文会做到十分克制,不会在虚拟线程之外的地方展开阅读和分析,以保证整篇文章都在聚焦虚拟线程, 本文主要由下图的内容构成,红色区域表示本篇核心:一个特别的Excutor executor.submit方法,这样就创建了虚拟线程,并在虚拟线程中执行业务逻辑: 现在去看创建VIRTUAL_EXECUTOR_SUPPLIER的代码就会特别清晰了,如下图,前面在JDK官方指导看到的 ,就会返回一个可用的executor,确保业务能执行下去 对于上图箭头3位置的做法,个人并不认同:我使用虚拟线程,就是想一口气创建成千上万线程,再肆无忌惮的使用,遇到不支持虚拟线程的场景,直接抛异常让我知道这条路走不通 后面更精彩 下一篇文章就是整个系列的终篇了,相比本文,终篇会简单很多,大家一起在轻松的氛围中畅谈线程技术的一个重要成员:ThreadLocal,看它在虚拟线程时代如何兴风作浪 你不孤单,欣宸原创一路相伴

    79330编辑于 2022-11-12
  • 来自专栏Lambda

    8.JUC线程高级-Condition和线程顺序执行

    有的时候我们希望线程按照希望的顺序依次执行,比如线程A,B,C,按照顺序依次执行,这时候就要用到阻塞和唤醒,之前的时候我们学到过wait()和nofity/notifyAll()这两个方法,这里我们使用 condition = lock.newCondition(); 要求 创建一个TestAlternate类,有三个方法loopA(),loopB(),loopC(),分别打印A,B,C 主函数中创建三个线程 /获得lock锁 private Lock lock = new ReentrantLock(); //创建三个condition对象用来await(阻塞)和signal(唤醒)指定的线程 Thread.currentThread().getName()+"-A"); number = 2;//使能第二个方法 c2.signal();//唤醒第二个线程 loopA,A2夺得了cpu执行权,结果发现此时A2的标记为number不是1,于是await,A2开始阻塞这个时候释放锁和资源,然后B,C线程得到cpu执行权按照顺序执行完毕,此时A的标志位是1,此时

    41610编辑于 2022-04-13
  • 来自专栏程序员

    深入剖析进程、线程虚拟内存

    线程的性能陷阱线程创建和切换开销:每个线程的创建需要分配栈空间(通常8MB)、线程控制块(TCB)等资源。 进程与线程的本质区别进程:资源的容器进程是操作系统进行资源分配的基本单位,它提供了一个执行环境,包括:独立的地址空间:每个进程有自己的虚拟地址空间,通过页表隔离资源句柄表:文件描述符、信号处理程序、用户权限等执行上下文 ;structmm_struct{pgd_t*pgd;//页全局目录(页表根)structvm_area_struct*mmap;//虚拟内存区域链表atomic_tmm_users;//使用该地址空间的线程数 (&attr,8*1024*1024);//8MB栈pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);//创建线程pthread_ttid _t*)(pdpt_base+pdpt_idx*8);//...继续遍历returnphysical_address;}页表:虚拟内存的核心数据结构展开代码语言:CAI代码解释//x86-64页表项结构

    29110编辑于 2025-12-08
领券