我只是在判断Coroutine调度员的行为.因此,我试图了解每个调度程序可以创建多少个线程.为了判断这一点,我创建了一个从1到1_000_000的循环语句.

在每个循环迭代中,我使用Dispatcher.IO创建了一个协程,但是当我看到输出时,它并没有创建1_000_000协程,所有这些都是DefaultDispatcher-Worker线程,并且它总是在40000-50000范围内随机停止执行.

但是,当我用Dispatcher.UnLimited替换Dispatcher.IO时,它实际上确实创建了所有1_000_000个协程,并且所有这些都是在主线程上创建的.

因此,我需要一些帮助来理解Dispatcher.IO在这种情况下失败的原因.

Dispatcher.IO:

fun main() {
    println("Start of main")

    val handler = CoroutineExceptionHandler { _, e -> e.printStackTrace() }

    runBlocking {
        for (i in 1..1000000) {
            CoroutineScope(Dispatchers.IO + CoroutineName("Dispatchers.IO")).launch(handler) {
                println("${Thread.currentThread().name}  task number is :$i")
            }
        }
    }
    println("End of main")
}

Dispatchers.Unconfined

fun main() {
    println("Start of main")

    val handler = CoroutineExceptionHandler { _, e ->
        e.printStackTrace()
    }

    runBlocking {
        for (i in 1..1000000) {
            CoroutineScope(Dispatchers.Unconfined + CoroutineName("Dispatchers.Unconfined")).launch(handler) {
                println("${Thread.currentThread().name}  task number is :$i")
            }
        }
    }
    println("End of main")
}

提前谢谢你

推荐答案

但当我看到输出时,它并没有创建1_000_000协程,并且 所有这些都是DefaultDispatcher-Worker线程,它总是停止 在40000-50000范围内随机执行.

这样做的原因,我相信是因为您没有等待所有的子协同 routine 完成,并且您的程序过早退出.

在下面的代码中,在名为jobs的列表中收集了Job个实例.在循环之后,jobs.joinAll()使执行等待所有子协同 routine 完成.

有趣的是,执行时间Dispatchers.IODispatchers.Unconfined之间的差异.

  • Dispatchers.IO:已用时间4.040274590
  • Dispatchers.Unconfined:已用时间959.173375ms

将挂起的delay(1)添加到循环中时,Dispatchers.Unconfined会将线程从main更改为kotlinx.coroutines.DefaultExecutor.

Dispatchers.Unconfined以严格的顺序1..1_000_000执行.

Coroutines basics

在AMD 8核Ubuntu 20.04上测试.

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.time.ExperimentalTime
import kotlin.time.measureTime

@OptIn(ExperimentalTime::class)
fun main() {

    println("Start of main")

    measureTime {
        runBlocking {

            val jobs = mutableListOf<Job>()

            repeat(1_000_000) { index ->
                jobs.add(launch(Dispatchers.IO) {
                    println("${Thread.currentThread().name}  task number is :${index + 1}")
                })
            }

            /** wait until child coroutines complete */
            jobs.joinAll()

            println("End of main")
        }
    }.also { duration -> println("Elapsed time: $duration") }
}

Android相关问答推荐

Android Compose Lazy柱形实时UI更改

理解修饰符<;方法>;与修饰符<;方法>;:效果和行为解释(Android开发者Jetpack Compose)

替换- prop -中的值(adb shell getprop)

LocalContext.current的问题(@Composable调用只能从@Composable函数的上下文发生)

如何将我的Android应用程序(Kotlin)中的图像分享给其他应用程序?

Jetpack Compose主导航中的全屏图标列表

在内部创建匿名对象的繁忙循环调用函数会产生开销吗?

如何检测低性能 Android 设备进行条件动画渲染?

从我的 Android 应用程序发送到 Gin 时失败,但从 Postman 发送到 Gin 时成功

同样的参数值下,为什么requiredSizeIn不等于requiredWidthIn + requiredHeightIn?

Android Jetpack Compose全宽度抽屉优化

如何在每次显示可组合项时执行代码(并且只执行一次)

在 react native 中设置 react-native-paper 组件的样式

在 Jetpack Compose 中自动滚动后面的项目

JCenter 是否永久关闭(10 月 31 日)?

如何在 compose 中使用 BottomSheetScaffold 为底页设置半展开高度?

如何使用 ConstraintLayout 链接两个文本

Jetpack Compose:对角拆分卡片并将内容放入其中

如何在 flow.stateIn() 之后从流中的另一个函数发出emits ?

如何删除 Ktor 客户端 2.0.0 的默认标头