为后端应用程序设置 kotlin 协程范围的正确方法
Correct way to set kotlin coroutine scope for backend app
设置协程范围的正确方法是什么 -
1.Implementing 范围
@Service
class MyServiceImpl : MyService, CoroutineScope {
private val job: Job = Job()
override val coroutineContext: CoroutineContext
get() = job + Executors.newFixedThreadPool(100).asCoroutineDispatcher()
override fun get(): String {
launch {....}
return "Result"
}}
`
2. 没有实施
@Service
class MyServiceImpl : MyService {
private val scope = Executors.newFixedThreadPool(100).asCoroutineDispatcher()
override fun get(): String {
GlobalScope.launch(scope) {....}
return "Result"
}}
或者只是在没有任何上下文的情况下使用 GlobalScope?
没有正确的方法,三种变体在不同的场景下都有用。
- 实现自己的协程作用域:
如果协程的生命周期取决于另一个对象的生命周期。在 UI 应用程序中特别有用,例如Android,如果需要销毁所有挂起的协程,当起始activity被销毁时,见https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md#structured-concurrency-lifecycle-and-coroutine-parent-child-hierarchy。
从线程池创建作用域:如果您的协程应该运行在公共线程池中。在这种情况下,新协程的生命周期不依赖于这个范围,而是依赖于外部协程:
val fixedThreadPoolContext = newFixedThreadPoolContext(100, "background")
launch(Dispatchers.Main) {
withContext(fixedThreadPoolContext) {
//parent job is from the outer coroutine
}
//or
val asyncResult = async(fixedThreadPoolContext) {
//parent job is from the outer coroutine
}
}
使用全局范围: 如果你喜欢启动一些不依赖于任何其他对象的后台协程。通常最好提供一个绑定到您的应用程序对象或某些全局单例的自己的范围。然后你可以提供你自己的异常处理器等
对于后端服务,我会使用自己的全局线程池调度程序然后您可以控制大小。请注意,GlobalScope 使用 CPU 计数作为参数来定义池大小。这对于 CPU 有界任务非常有用,但不适用于 IO 任务,例如数据库访问。
设置协程范围的正确方法是什么 -
1.Implementing 范围
@Service
class MyServiceImpl : MyService, CoroutineScope {
private val job: Job = Job()
override val coroutineContext: CoroutineContext
get() = job + Executors.newFixedThreadPool(100).asCoroutineDispatcher()
override fun get(): String {
launch {....}
return "Result"
}}
` 2. 没有实施
@Service
class MyServiceImpl : MyService {
private val scope = Executors.newFixedThreadPool(100).asCoroutineDispatcher()
override fun get(): String {
GlobalScope.launch(scope) {....}
return "Result"
}}
或者只是在没有任何上下文的情况下使用 GlobalScope?
没有正确的方法,三种变体在不同的场景下都有用。
- 实现自己的协程作用域: 如果协程的生命周期取决于另一个对象的生命周期。在 UI 应用程序中特别有用,例如Android,如果需要销毁所有挂起的协程,当起始activity被销毁时,见https://github.com/Kotlin/kotlinx.coroutines/blob/master/ui/coroutines-guide-ui.md#structured-concurrency-lifecycle-and-coroutine-parent-child-hierarchy。
从线程池创建作用域:如果您的协程应该运行在公共线程池中。在这种情况下,新协程的生命周期不依赖于这个范围,而是依赖于外部协程:
val fixedThreadPoolContext = newFixedThreadPoolContext(100, "background") launch(Dispatchers.Main) { withContext(fixedThreadPoolContext) { //parent job is from the outer coroutine } //or val asyncResult = async(fixedThreadPoolContext) { //parent job is from the outer coroutine } }
使用全局范围: 如果你喜欢启动一些不依赖于任何其他对象的后台协程。通常最好提供一个绑定到您的应用程序对象或某些全局单例的自己的范围。然后你可以提供你自己的异常处理器等
对于后端服务,我会使用自己的全局线程池调度程序然后您可以控制大小。请注意,GlobalScope 使用 CPU 计数作为参数来定义池大小。这对于 CPU 有界任务非常有用,但不适用于 IO 任务,例如数据库访问。