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

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

Java 中的虚拟线程,也叫做协程或“轻量级线程”,它诞生于 JDK 19(预览 API),正式发布于 JDK 21,它是一种在 Java 虚拟机(JVM)层面实现的逻辑线程,不直接和操作系统的物理线程一一对应,因此它可以减少上下文切换所带来的性能开销。

操作系统线程、普通线程(Java 线程)和虚拟线程的关系如下:
image.png

虚拟线程使用

虚拟线程的创建方式,主要有以下 4 种:

  1. Thread.startVirtualThread(Runnable task)
  2. Thread.ofVirtual().unstarted(Runnable task)
  3. Thread.ofVirtual().factory()
  4. Executors.newVirtualThreadPerTaskExecutor()

具体示例如下。

1.startVirtualThread

创建虚拟线程,并直接启动执行任务:

// 创建并启动虚拟线程
Thread.startVirtualThread(() -> {
   
   
    System.out.println("Do virtual thread.");
});

2.unstarted

只创建虚拟线程,但不直接启动:

// 创建虚拟线程
Thread vt = Thread.ofVirtual().unstarted(()->{
   
   
    System.out.println("Do virtual thread.");
});
// 运行虚拟线程
vt.start();

3.factory

先创建虚拟线程工厂,然后再使用工厂创建虚拟线程,之后再调用 start() 方法进行执行:

// 创建虚拟线程工厂
ThreadFactory tf = Thread.ofVirtual().factory();
// 创建虚拟线程
Thread vt = tf.newThread(()->{
   
   
    System.out.println("Do virtual thread.");
});
// 运行虚拟线程
vt.start();

4.newVirtualThreadPerTaskExecutor

使用线程池的方式创建虚拟线程:

// 创建一个支持虚拟线程的线程池
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
executor.submit(()->{
   
   
    System.out.println("Do virtual thread.");
});

虚拟线程 VS 普通线程

虚拟线程和普通线程的区别主要体现在以下几点:

  1. 普通线程是和操作系统的物理线程是一一对应的,而虚拟线程是 JVM 层面的逻辑线程,并不和操作系统的物理线程一一对应,它可以看作是轻量级的线程。
  2. 普通线程默认创建的是用户线程(而守护线程),而虚拟线程是守护线程,并且其守护线程的属性不能被修改,如果修改就会报错,如下图所示:

  1. 虚拟线程由 JVM 调度和使用,避免了普通线程频繁切换的性能开销,所以相比于普通的线程来说,运行效率更高。

    小结

    线程是轻量级的进程,而虚拟线程则是轻量级的线程,虚拟线程是 JVM 层面实现的逻辑线程,不直接和操作系统的物理线程一一对应,因此使用它可以减少线程上下文切换所带来的性能开销。它和普通线程的线程类型也不同,普通线程是默认是用户线程类型,而虚拟线程则是守护线程(而且不能被修改)。

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

相关文章
|
3月前
|
Oracle Java API
虚拟线程:Java的新利器?
作者通过本文梳理了自己对虚拟线程的理解,顺便捋一捋Java线程的过去、现在和未来。ps:写这篇文章的时候,Java 19刚刚发布,而现在Java 21已经正式GA了,不过虚拟线程的API和底层实现并没有什么变化。
|
1月前
|
算法 NoSQL Java
Springboot3新特性:GraalVM Native Image Support和虚拟线程(从入门到精通)
这篇文章介绍了Spring Boot 3中GraalVM Native Image Support的新特性,提供了将Spring Boot Web项目转换为可执行文件的步骤,并探讨了虚拟线程在Spring Boot中的使用,包括如何配置和启动虚拟线程支持。
67 9
Springboot3新特性:GraalVM Native Image Support和虚拟线程(从入门到精通)
|
1月前
|
Java 关系型数据库 MySQL
如何用java的虚拟线程连接数据库
本文介绍了如何使用Java虚拟线程连接数据库,包括设置JDK版本、创建虚拟线程的方法和使用虚拟线程连接MySQL数据库的示例代码。
34 6
如何用java的虚拟线程连接数据库
|
2月前
|
缓存 Java 应用服务中间件
Java虚拟线程探究与性能解析
本文主要介绍了阿里云在Java-虚拟-线程任务中的新进展和技术细节。
|
2月前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)
|
2月前
|
消息中间件 前端开发 NoSQL
面试官:线程池遇到未处理的异常会崩溃吗?
面试官:线程池遇到未处理的异常会崩溃吗?
73 3
面试官:线程池遇到未处理的异常会崩溃吗?
|
2月前
|
消息中间件 存储 前端开发
面试官:说说停止线程池的执行流程?
面试官:说说停止线程池的执行流程?
50 2
面试官:说说停止线程池的执行流程?
|
19天前
|
监控 Java API
|
2月前
|
消息中间件 前端开发 NoSQL
面试官:如何实现线程池任务编排?
面试官:如何实现线程池任务编排?
32 1
面试官:如何实现线程池任务编排?
|
24天前
|
Java 应用服务中间件 测试技术
Java21虚拟线程:我的锁去哪儿了?
【10月更文挑战第8天】
30 0