网站首页 > java教程 正文
前言
最近面试官问,JAVA虚拟线程你了解吗?你只听说过线程,竟还有虚拟线程这回事?
Java 虚拟线程是 JDK 19 中引入的一项新功能。它有可能在减少内存消耗的基础上提高应用程序的可用性、吞吐量,那么本文就带大家了解一下JAVA虚拟线程究竟是怎么样一回事。
线程生命周期
我们先来回顾下线程在线程池中的整个生命周期吧,如下图所示:
- 线程在线程池中创建
- 线程在池中等待新请求的到来
- 一旦新的请求到来,线程接收请求并调用后端数据库来处理这个请求。
- 线程等待后端数据库的响应
- 一旦响应从数据库返回,线程处理它,并将响应发送回客户
- 线程返回线程池
步骤 #2 到 #6 将不断重复,直到应用程序关闭。
你会发现线程实际上只在步骤#3 和#5 中进行实际工作。在所有其他步骤(即步骤#1、步骤#2、步骤#4、步骤#6)中,它基本上是在等待(或什么都不做)。在大多数应用程序中,大量线程在其生命周期的大部分时间里都处于等待状态。
平台线程架构
我们在来看看Linux系统中线程的架构,平台应用中的线程都映射到一个操作系统线程,如下图所示:
在之前的JVM(Java Virtual Machine)版本中,只有一种线程。它被称为“经典”或“平台”线程。每当创建平台线程时,都会为其分配一个操作系统线程。只有当平台线程退出(即死亡)JVM 时,该操作系统线程才可以执行其他任务。在此之前,它无法执行任何其他任务。基本上,平台线程和操作系统线程之间存在 1:1 的映射。
根据这种架构,操作系统线程将在平添的线程生命周期的步骤#1、步骤#2、步骤#4、步骤#6 中被不必要地锁定,即使这时候线程没有做任何工作,只是傻傻地等待在那。由于操作系统中的线程是宝贵且有限的资源,因此在该平台线程架构中大量浪费了时间。
虚拟线程架构
我们现在看看虚拟线程的架构,是如何处理上面所说的问题的呢?实际上,在虚拟线程架构下,操作系统线程不会一开始就分配给平台线程,而是直到需要执行实际工作时,如下图所示:
为了高效地使用底层操作系统线程,在 JDK 19 中引入了虚拟线程。在这种新架构中,虚拟线程只有在执行实际工作时才会分配给平台线程。根据上述线程的生命周期,只有在步骤#3 和步骤#5 期间,虚拟线程才会分配给平台线程(反过来使用操作系统线程)执行。在所有其他步骤中,虚拟线程将作为对象驻留在 Java 堆内存区域中,就像其他的普通对象一样。所以说,虚拟线程是很轻量级且高效。
如何创建虚拟线程?
我们现在看看如何创建一个虚拟线程,代码如下:
Runnable task = () -> { System.out.println("Hello Virtual Thread!"); };
Thread.startVirtualThread(task);
- 通过Thread.startVirtualThread() 可以快速创建出虚拟线程
另外,还可以使用以下 API 创建 Java 虚拟线程:
1. Thread.ofVirtual().start(Runnable);
2. Thread.ofVirtual().unstarted(Runnable);
3. Executors.newVirtualThreadPerTaskExecutor();
4. Executors.newThreadPerTaskExecutor(ThreadFactory);
虚拟线程的优点
由于其优雅的架构,虚拟线程提供了几个优点:
- 提高应用可用性
- 提高应用吞吐量
- 减少出现这样的一次'OutOfMemoryError: unable to create new native thread'
- 减少应用程序内存消耗
虚拟线程的缺点
- 虚拟线程默认是守护线程,截至目前,设置Thread.setPriority(int)没有任何效果,但可能会在 JDK 的更高版本中发生变化。
- 虚拟线程不支持stop()、suspend()或resume()方法,如果调用它们会抛出异常。
总结
本文讲解了虚拟线程是什么,以及如何工作的。那它究竟适合于什么样的一个场景呢?当有大量不受 CPU 限制的任务时,虚拟线程有助于提高吞吐量。I/O 密集型任务是受益于虚拟线程的主要任务,这些任务包括从队列中读取数据、等待传入的 Web 请求、数据库查询等。
欢迎关注个人公众号【JAVA旭阳】交流学习!
猜你喜欢
- 2025-05-30 线程池的使用及ThreadPoolExecutor源码分析
- 2025-05-30 面试官:什么是虚拟线程?为什么要有虚拟线程?
- 2025-05-30 「超级详细」Java线程实现原理
- 2025-05-30 并发编程之ThreadPoolExecutor线程池原理解析
- 2025-05-30 阿里资深架构推荐学习四本实战书籍:MySQL+Redis+Kfaka+多线程
- 2025-05-30 杰哥教你面试之一百问系列:java多线程
- 2025-05-30 面试突击29:说一下线程池7个参数的含义?
- 2025-05-30 一个 tomcat 项目使用多个线程池还是一个线程池 ?
- 2025-05-30 一个注解 —— 完美实现分布式锁
- 2025-05-30 Java 线程的生命周期及各阶段状态
你 发表评论:
欢迎- 06-04C++优先级调度队列(Priority Queue)
- 06-04数据结构与算法-优先队列(优先队列 数组实现)
- 06-04什么是优先队列?(优先队列原理)
- 06-04终于有架构大牛把分布式系统概念讲明白了,竟然用了足足800页
- 06-04分布式事物如何保证接口请求顺序性?
- 06-04微服务下分布式事务模式的详细对比
- 06-04彻底掌握分布式事务2PC、3PC模型(分布式事务 三阶段)
- 06-04分布式事务最全详解(看这篇就够了)
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)