Kotlin:创建自定义 CoroutineContext
Kotlin: Create custom CoroutineContext
我在 API 后端使用 Kotlin。我不想在 common pool
中 运行 数据库查询。基本上,我想创建一个 CoroutineContext
,它有许多与数据库匹配的线程 maximumPoolSize
。
完成此任务的最佳方法是什么(通常和针对我的特定用例)?我知道 Kotlin 提供开箱即用的 contexts
,但创建我自己的最佳方法是什么?
奖励问题:如果我的 jdbc 连接池大小为 3,使用线程池大小为 3 的协程上下文是否有意义?这样能保证最好的并发吗?
您可以使用 newFixedThreadPoolContext
:
创建一个由具有固定线程数的线程池支持的 CoroutineContext
val myContext = newFixedThreadPoolContext(nThreads = 3, name = "My JDBC context")
是的,将线程池的大小与连接池的大小相匹配似乎是个好主意,因为这样一来,您的线程(假设它们每次都使用一个连接)将始终准备好一个数据库连接他们 - here's 一个博客 post 建议相同。
函数 newFixedThreadPoolContext
现在被认为在当前版本的 Kotlin 协程 (1.3.0) 中已过时,因为它现在用 @ObsoleteCoroutinesApi
注释,如果您尝试,它会发出警告使用。文档还说以后会被替换掉
现在推荐的创建CoroutineContext的方式是通过
Executors.newFixedThreadPool(3).asCoroutineDispatcher()
所以一个完整的导入示例,其中还创建了一个 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)
}
zsmb13 的答案完美无缺,但 Android Studio 警告说 newFixedThreadPoolContext
是一个微妙的问题 API,只应在特定情况下使用。
有限并行的推荐替代方案(截至 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.
因此,另一种解决方案是在用于数据库连接的线程池上创建一个视图,例如:
val dbDispatcher = Dispatchers.IO.limitedParallelism(maximumPoolSize)
然后将其用作协程调度程序。
我在 API 后端使用 Kotlin。我不想在 common pool
中 运行 数据库查询。基本上,我想创建一个 CoroutineContext
,它有许多与数据库匹配的线程 maximumPoolSize
。
完成此任务的最佳方法是什么(通常和针对我的特定用例)?我知道 Kotlin 提供开箱即用的 contexts
,但创建我自己的最佳方法是什么?
奖励问题:如果我的 jdbc 连接池大小为 3,使用线程池大小为 3 的协程上下文是否有意义?这样能保证最好的并发吗?
您可以使用 newFixedThreadPoolContext
:
CoroutineContext
val myContext = newFixedThreadPoolContext(nThreads = 3, name = "My JDBC context")
是的,将线程池的大小与连接池的大小相匹配似乎是个好主意,因为这样一来,您的线程(假设它们每次都使用一个连接)将始终准备好一个数据库连接他们 - here's 一个博客 post 建议相同。
函数 newFixedThreadPoolContext
现在被认为在当前版本的 Kotlin 协程 (1.3.0) 中已过时,因为它现在用 @ObsoleteCoroutinesApi
注释,如果您尝试,它会发出警告使用。文档还说以后会被替换掉
现在推荐的创建CoroutineContext的方式是通过
Executors.newFixedThreadPool(3).asCoroutineDispatcher()
所以一个完整的导入示例,其中还创建了一个 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)
}
zsmb13 的答案完美无缺,但 Android Studio 警告说 newFixedThreadPoolContext
是一个微妙的问题 API,只应在特定情况下使用。
有限并行的推荐替代方案(截至 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.
因此,另一种解决方案是在用于数据库连接的线程池上创建一个视图,例如:
val dbDispatcher = Dispatchers.IO.limitedParallelism(maximumPoolSize)
然后将其用作协程调度程序。