chr*_*ris 7 java kotlin spring-boot spring-webflux kotlin-coroutines
想象一下,我有一个使用 Kotlin 实现的 Spring WebFlux 控制器,如下所示:
\n@RestController\n@RequestMapping("/api/foo")\nclass MyController {\n @GetMapping\n suspend fun getFoo(): FooResource {\n return withContext(Dispatchers.IO) {\n // fetch some resource with some expensive blocking IO call\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n根据我理解 WebFlux 并发模型的方式,只有一个线程可用于处理请求,因此如果由于某种原因我无法避免阻塞 IO 调用,我需要以某种方式将其卸载到另一个线程。据推测,助手kotlinx.coroutines.withContext正是这样做的,调度程序IO是专门为这种用例而设计的。“我在几篇博客文章中看到过这种模式,所以这似乎是常识。
然而,[文档Dispatchers.IO说:
\n\n此调度程序与默认调度程序共享线程,因此使用 withContext(Dispatchers.IO) { ... } 不会导致实际切换到另一个线程 \xe2\x80\x94 通常执行会在同一线程中继续。由于线程共享,在通过 IO 调度程序进行操作期间可以创建(但不使用)超过 64 个(默认并行)线程。
\n
所以这让我想知道:如果 WebFlux 只使用单个“主线程”来处理请求,并且即使我正在使用,阻塞 IO 仍可能在该线程中发生withContext(Dispatchers.IO):此模式是否可以安全使用,如果不是,还有什么我应该做什么?
是的,它是安全的,你理解withContext正确。
您在这里提到的文档只是讨论了在调度程序之间切换时的优化(Dispatchers.IO这避免了上下文切换)。IODefault
从/线程池withContext(Dispatchers.IO)以外的其他线程使用将正确(并且始终)将上下文切换到该 IO 线程池,根据需要启动新线程来处理阻塞 IO,因此这应该是您的情况下的方法。DefaultIO
| 归档时间: |
|
| 查看次数: |
1388 次 |
| 最近记录: |