[英]Kotlin: Create custom CoroutineContext
I'm using Kotlin in my API backend.我在 API 后端使用 Kotlin。 I don't want to run db queries in the
common pool
.我不想在
common pool
运行数据库查询。 Basically, I want to create a CoroutineContext
that has a number of threads that matches the database maximumPoolSize
.基本上,我想创建一个
CoroutineContext
,它有许多与数据库maximumPoolSize
匹配的线程。
What's the best way to accomplish this (generally and for my specific use case)?完成此操作的最佳方法是什么(通常和针对我的特定用例)? I know Kotlin provides
contexts
out of the box, but what's the best approach to create my own?我知道 Kotlin 提供开箱即用的
contexts
,但创建我自己的上下文的最佳方法是什么?
Bonus question: If I have a jdbc connection pool size of 3, does it make sense to use a coroutinecontext with a thread pool size of 3?奖励问题:如果我有一个大小为 3 的 jdbc 连接池,使用线程池大小为 3 的 coroutinecontext 是否有意义? Can this guarantee the best concurrency possible?
这样能保证最好的并发吗?
You can create a CoroutineContext
that's backed by a thread pool with a fixed number of threads using newFixedThreadPoolContext
: 您可以使用
CoroutineContext
创建一个由具有固定线程数的线程池支持的newFixedThreadPoolContext
:
val myContext = newFixedThreadPoolContext(nThreads = 3, name = "My JDBC context")
And yes, it seems like a good idea to match your thread pool's size to the connection pool's size, because that way your threads (assuming they each use one connection at a time) will always have a database connection ready for them - here's a blog post suggesting the same. 是的,将线程池的大小与连接池的大小匹配似乎是一个好主意,因为这样一来,您的线程(假设它们每个一次使用一个连接)将始终为它们准备好数据库连接- 这是一个博客暗示相同。
The function newFixedThreadPoolContext
is now considered obsolete with current version of Kotlin coroutines (1.3.0), as it is now annotated with @ObsoleteCoroutinesApi
and it will give you a warning if you would try to use. 现在,函数
newFixedThreadPoolContext
在Kotlin协程(1.3.0)的当前版本中被认为已作废,因为它现在已用@ObsoleteCoroutinesApi
了注释,如果尝试使用它将发出警告。 The documentation also states that it will be replaced in the future. 该文档还指出,将来会替换它。
The recommended way to create a CoroutineContext is now through 现在建议通过以下方法创建CoroutineContext
Executors.newFixedThreadPool(3).asCoroutineDispatcher()
So a complete example with imports, where also creating a CoroutineScope, would look like this 因此,带有导入的完整示例(其中还要创建一个CoroutineScope)看起来像这样
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.asCoroutineDispatcher
import java.util.concurrent.Executors
import kotlin.coroutines.CoroutineContext
fun coroutineScope(threads: Int): CoroutineScope {
val context: CoroutineContext = Executors.newFixedThreadPool(threads).asCoroutineDispatcher()
return CoroutineScope(context)
}
The answer by zsmb13 works perfectly, but Android Studio warns that newFixedThreadPoolContext
is a delicate API and should only be used in specific cases. zsmb13 的答案完美无缺,但 Android Studio 警告说
newFixedThreadPoolContext
是一个微妙的 API 并且只能在特定情况下使用。
The recommended alternative (as of Spring 2022) for limited parallelism is limitedParallelism
:有限并行的推荐替代方案(截至 Spring 2022)是
limitedParallelism
:
Creates a view of the current dispatcher that limits the parallelism to the given value. The resulting view uses the original dispatcher for execution, but with the guarantee that no more than parallelism coroutines are executed at the same time.
This method does not impose restrictions on the number of views or the total sum of parallelism values, each view controls its own parallelism independently with the guarantee that the effective parallelism of all views cannot exceed the actual parallelism of the original dispatcher.
(from https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/limited-parallelism.html ) (来自https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-coroutine-dispatcher/limited-parallelism.html )
So an alternative solution would be to create a view on the thread pool used for the db connection like:因此,另一种解决方案是在用于数据库连接的线程池上创建一个视图,例如:
val dbDispatcher = Dispatchers.IO.limitedParallelism(maximumPoolSize)
and then use this as coroutine dispatcher.然后将其用作协程调度程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.