前言
在2022年9月20日Java19
发布啦,再次新增了几个特性,其中最吸引我的就是virtual Thread虚拟线程了,官方提供了虚拟线程的预览,这是Project Loom 的主要成果。
虚拟线程是为了提高Java并发变成的可扩展性,是一种轻量级线程。它并不是为了替代原先的Thread线程,而是一种扩展,类似于Go语言中的协程,可以避免线程的上下文切换所带来的额外消耗。
在原先的线程模型中,每个Java线程都对应一个操作系统的线程,但virtual Thread则可以将多个虚拟线程对应到一个操作系统线程上去。
基本使用
创建虚拟线程
VirtualThread
继承于Thread,因此API
是互相兼容的。Thread类提供了两个工程方法来创建平台线程和虚拟线程。
ofPlatform
:创建平台线程ofVirtual
:创建虚拟线程
1 | Thread thread = Thread.ofVirtual().name("duke").unstarted(runnable); |
上面的代码创建了一个线程名为duke的线程,但并没有启动,可以通过start
方法来启动。
或者我们直接使用Thread.startVirtualThread(Runnable)
方法来创建并启动虚拟线程
判断是否为虚拟线程
官方还提供了Thread.isVirtual()
方法来判断该线程是否为虚拟线程。
虚拟线程总为守护线程
虚拟线程总为守护线程,并不会受Thread.SetDaemon
方法的影响,这意味这如果没有平台线程在运行的话,程序会直接退出。
虚拟线程总是固定优先级
在目前发布的JDK19的版本中,虚拟线程总是为Thread.NORM_PRIORITY
固定优先级,并不会受Thread.setPriority
方法的影响。
不支持部分Thread的方法
虚拟线程并不支持 stop
、suspend
、resume
等线程调度方法,当在虚拟线程上运行会抛出异常。
支持虚拟线程线程池(不推荐)
官方也提供了虚拟线程池的相关API,不过官方并不推荐将虚拟线程池化。这是因为虚拟线程的创建并不会消耗很多资源,它是轻量级的,应该为每一个请求都创建一个新的虚拟线程,这样也可以避免一些线程安全的问题。
1 | try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { |
关于性能
根据官方的说法,虚拟线程可以减少线程的上下文切换,以提升并发效率。
查看网上的数据对比貌似也确实如此,但也同样有使用虚拟线程反而执行速度变慢的问题。