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

服务端 服务端 1699 人阅读 | 0 人回复

发表于 2023-12-20 18:12:43 | 显示全部楼层 |阅读模式

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

虚拟线程使用
虚拟线程的创建方式,主要有以下 4 种:
  • Thread.startVirtualThread(Runnable task)
  • Thread.ofVirtual().unstarted(Runnable task)
  • Thread.ofVirtual().factory()
  • Executors.newVirtualThreadPerTaskExecutor()
具体示例如下。
1.startVirtualThread
创建虚拟线程,并直接启动执行任务:
  1. Thread.startVirtualThread(() -> {
  2.     System.out.println("Do virtual thread.");
  3. });
复制代码
2.unstarted
只创建虚拟线程,但不直接启动:
  1. // 创建虚拟线程
  2. Thread vt = Thread.ofVirtual().unstarted(()->{
  3.     System.out.println("Do virtual thread.");
  4. });
  5. // 运行虚拟线程
  6. vt.start();
复制代码
3.factory
先创建虚拟线程工厂,然后再使用工厂创建虚拟线程,之后再调用 start() 方法进行执行:
  1. // 创建虚拟线程工厂
  2. ThreadFactory tf = Thread.ofVirtual().factory();
  3. // 创建虚拟线程
  4. Thread vt = tf.newThread(()->{
  5.     System.out.println("Do virtual thread.");
  6. });
  7. // 运行虚拟线程
  8. vt.start();
复制代码
4.newVirtualThreadPerTaskExecutor
使用线程池的方式创建虚拟线程:
  1. // 创建一个支持虚拟线程的线程池
  2. ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
  3. executor.submit(()->{
  4.     System.out.println("Do virtual thread.");
  5. });
复制代码
虚拟线程 VS 普通线程
虚拟线程和普通线程的区别主要体现在以下几点:
  • 普通线程是和操作系统的物理线程是一一对应的,而虚拟线程是 JVM 层面的逻辑线程,并不和操作系统的物理线程一一对应,它可以看作是轻量级的线程。
  • 普通线程默认创建的是用户线程(而守护线程),而虚拟线程是守护线程,并且其守护线程的属性不能被修改,如果修改就会报错,如下图所示:
2.jpg


3、虚拟线程由 JVM 调度和使用,避免了普通线程频繁切换的性能开销,所以相比于普通的线程来说,运行效率更高。
小结
线程是轻量级的进程,而虚拟线程则是轻量级的线程,虚拟线程是 JVM 层面实现的逻辑线程,不直接和操作系统的物理线程一一对应,因此使用它可以减少线程上下文切换所带来的性能开销。它和普通线程的线程类型也不同,普通线程是默认是用户线程类型,而虚拟线程则是守护线程(而且不能被修改)。



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则