【发布时间】:2021-09-05 05:16:46
【问题描述】:
想象一下,我有一个用 Kotlin 实现的 Spring WebFlux 控制器,看起来像这样:
@RestController
@RequestMapping("/api/foo")
class MyController {
@GetMapping
suspend fun getFoo(): FooResource {
return withContext(Dispatchers.IO) {
// fetch some resource with some expensive blocking IO call
}
}
}
我理解 WebFlux 的并发模型的方式,只有一个线程可以处理请求,所以如果我由于某种原因无法避免阻塞 IO 调用,我需要以某种方式将其卸载到另一个线程。 kotlinx.coroutines.withContext 助手应该就是这样做的,IO 调度程序是专门为这种用例设计的。`我在几篇博客文章中看到了这种模式,所以这似乎是常识。
但是,[Dispatchers.IO 上的文档说:
此调度程序与默认调度程序共享线程,因此使用 withContext(Dispatchers.IO) { ... } 不会导致实际切换到另一个线程 - 通常在同一线程中继续执行。由于线程共享,在通过 IO 调度程序进行操作期间可以创建(但不使用)超过 64 个(默认并行度)线程。
所以这让我想知道:如果 WebFlux 只使用一个“主线程”来处理请求,并且即使我使用 withContext(Dispatchers.IO),阻塞 IO 仍然可能发生在这个线程中:这种模式可以安全使用吗?如果没有,我还应该怎么做?
【问题讨论】:
标签: java spring-boot kotlin spring-webflux kotlin-coroutines