我只是在判断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应用程序上使用Room数据库时,是否可以预先填充数据

AndroidX Media3 迁移指南

使用 List 和 LazyColumn 重新组合所有项目

如何在卡片视图右侧添加箭头

使用 async 向网络发出并行请求并在supervisorScope中处理它们

是否可以在 Android 应用程序的 Wifi 设置中为 DNS 服务器设置自定义 IP?

判断 AAR 元数据时发现 Android 问题:androidx.core:core:1.12.0-alpha01 和 androidx.core:core-ktx:1.12.0-alpha01

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

Jetpack Compose UI - 在 AlertDialog 中单击时按钮宽度会发生变化

为片段设置主题

Jetpack Compose Material3 禁用 ListItem

如何在 Jetpack Compose 中为中心对齐设置动画?

为什么我不能直接记住 mutableStateOf 可组合函数?

Android Studio 错误要求依赖它的库和应用程序针对 Android API 的 33 版或更高版本进行编译.

优化 Room 数据库迁移

ObjectBox,如何在冲突中放弃一切迁移?

即使我在单选按钮上明确设置了选中状态,RecyclerView 中的单选按钮也会随机取消选中

Android:如何获取具有纬度和经度的位置的图像

验证备份 ZIP 文件