简体   繁体   English

Kotlin:创建自定义CoroutineContext

[英]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.

相关问题 如何在 Kotlin 中创建数据类的表(在 RDBMS 中)? - How to create a table(in RDBMS) of a data class in Kotlin? jOOQ:如何在自定义时区创建时间戳(与JDBC一样)? - jOOQ: How to Create Timestamps in a Custom Time Zone (as with JDBC)? jdbc中的HSQL参考自定义类型create array语句 - HSQL reference custom type in jdbc create array statement 如何创建自定义 c3p0 ComboPooledDataSource 并在 tomcat context.xml 中引用 - How to create custom c3p0 ComboPooledDataSource and refer in tomcat context.xml 在Kotlin中编写JDBC驱动程序是否适用? - Is it applicable to write a JDBC driver in Kotlin? 使用自定义方法插入我的表不起作用,但如果我输入创建连接方法它工作正常 - Inserting into my table using a custom method is not working, but if I put in the create connection method it works fine 使用 UserDefined JDBC 提供程序通过 wsadmin 创建数据源槽时,不会出现数据源的自定义属性 (J2EEResourcePropertySet) - Custom properties (J2EEResourcePropertySet) of datasource do not appear when using UserDefined JDBC provider to create datasource trough wsadmin Kotlin 数据库连接错误 - Kotlin database connectivity error 使用 Kotlin Exposed 创建数据库后连接到数据库 - Connecting to a database after creating it with Kotlin Exposed Kotlin 协程与 Spring JPA 阻塞存储库 - Kotlin coroutines with Spring JPA blocking repository
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM