虚拟线程(Project Loom)能否与Spring WebFlux等响应式库高效结合?
Java 19中引入了虚拟线程(JEP-425)作为预览特性。
在研究了Java虚拟线程(Project Loom)的概念后——它有时被称为轻量级线程(或纤程、绿色线程),我十分关注其与响应式库结合的潜在用法,例如基于Project Reactor(响应式流实现)和Netty的Spring WebFlux,以高效处理阻塞调用。
如今大多数JVM实现将Java线程作为操作系统线程的轻量直接包装,这类线程有时被称为重量级、由操作系统管理的平台线程。
平台线程同一时间只能执行一个任务,而虚拟线程在当前执行的虚拟线程发起阻塞调用(如网络、文件系统、数据库调用)时,能够切换执行另一个虚拟线程。
在Reactor中处理阻塞调用时,我们通常采用官方推荐的以下结构:
Mono.fromCallable(() -> { return blockingOperation(); }).subscribeOn(Schedulers.boundedElastic());
在subscribeOn()中我们提供一个Scheduler,为执行该阻塞操作创建专用线程。但这意味着线程最终会被阻塞,由于我们仍使用传统线程模型,实际上会阻塞平台线程,这并非高效利用CPU资源的方式。
那么,我们能否直接将虚拟线程与响应式框架结合,用于处理阻塞调用?例如使用Executors.newVirtualThreadPerTaskExecutor()——该方法会创建一个为每个任务启动新虚拟线程的Executor,且创建的线程数量不受限制,代码如下:
Mono.fromCallable(() -> { return blockingOperation(); }).subscribeOn(Schedulers.fromExecutorService(Executors.newVirtualThreadPerTaskExecutor()));
这种方式能否开箱即用?能否在CPU资源利用效率和应用性能提升方面获得收益?这是否意味着我们可以轻松将响应式库与任何阻塞库/框架(例如基于JDBC的Spring Data JPA等)集成,使其“魔法般”变为非阻塞?
内容的提问来源于stack exchange,提问作者kerbermeister

