Java虚拟线程
在Java 19中引入了虚拟线程JEP-425作为预览功能。
在对Java虚拟线程(项目Loom)的概念进行一些调查后,有时被称为轻量级线程(或有时称为纤程或绿色线程),我对它们与反应式库的潜在用途非常感兴趣,例如基于Project Reactor(反应式流实现)和Netty的Spring WebFlux,以便高效地进行阻塞调用。
大多数JVM实现今天将Java线程实现为对操作系统线程的薄包装,有时称为重量级、由操作系统管理的平台线程。
虚拟线程可以在当前执行的虚拟线程进行阻塞调用(例如网络、文件系统、数据库调用)时切换到执行不同的虚拟线程,而平台线程一次只能执行一个线程。
我们如何在 Reactor 中处理阻塞调用?
所以,在处理 Reactor 中的阻塞调用时,我们使用 以下结构:
Mono.fromCallable(() -> {
return blockingOperation();
}).subscribeOn(Schedulers.boundedElastic());
在
subcribeOn()
中,我们提供了一个Scheduler
,它为执行阻塞操作创建了一个专用线程。然而,这意味着该线程最终会被阻塞,因此,由于我们仍然采用传统的线程模型,实际上会阻塞平台线程,这并不是处理CPU资源的高效方式。
问题如下:
所以,问题是,我们是否可以直接在响应式框架中使用虚拟线程来进行像这样的阻塞调用,例如使用Executors.newVirtualThreadPerTaskExecutor():
创建一个为每个任务启动新的虚拟线程的Executor。 Executor创建的线程数是无限的。
Mono.fromCallable(() -> {
return blockingOperation();
}).subscribeOn(Schedulers.fromExecutorService(Executors.newVirtualThreadPerTaskExecutor()));
能直接使用吗?我们是否能真正从这种方法中获得好处,以更高效地处理我们的CPU资源并提高应用程序的性能?这是否意味着我们可以轻松地将响应式库与任何阻塞库/框架集成,例如基于JDBC的Spring Data JPA和其他无数的库/框架,并且像魔术般地将它们转变为非阻塞的?