【问题标题】:Why does IO Dispatchers create more than 64 thread in Kotlin corotines?为什么 IO Dispatchers 在 Kotlin 协程中创建超过 64 个线程?
【发布时间】:2021-01-12 09:21:22
【问题描述】:

据我了解,Dispatchers.IO 可以创建的最大线程数为 64,但我的结果有点棘手。

这是我的代码。

repeat(500) {
    CoroutineScope(Dispatchers.IO).launch {
        println(Thread.currentThread().name)
    }
}

这就是结果。

...

DefaultDispatcher-worker-18
DefaultDispatcher-worker-46
DefaultDispatcher-worker-17
DefaultDispatcher-worker-47
DefaultDispatcher-worker-69
DefaultDispatcher-worker-64
DefaultDispatcher-worker-66
DefaultDispatcher-worker-67
DefaultDispatcher-worker-68
DefaultDispatcher-worker-41

...

为什么我的线程池计数大于 64? 这是否意味着我的实际线程已创建超过 64 个?

感谢您的阅读! 请帮帮我

【问题讨论】:

  • Dispatchers.IO 从 CommonPool 租用的最大线程数为 64。Dispatchers.Default 仍然可以创建更多线程,如果 Dispatchers.IO 中的协程都忙于你的核心数,Dispatchers.Default 仍然可以创建更多线程。 In playground,它的线程似乎没有超过 64 个。你是否也在其他调度程序中启动?
  • 不,这就是代码中的全部内容。并且 afik,默认调度程序可以创建多达 CPU 核心数量的线程。如果这是正确的,我认为 Default Dispatchers 将创建的最大线程数仅为 12...不是吗?为什么我的协程会这样工作?
  • 在我的例子中,我使用 IO Dispatchers 就是那个代码。所以即使你是对的,我的代码还是有点棘手。

标签: android kotlin kotlin-coroutines coroutine


【解决方案1】:

我不知道 Dispachers.IO 如何命名它的线程,但我一次只能运行 64 个协程。

如果您想将其限制为您拥有的 CPU 数量,您需要设置此系统属性:kotlinx.coroutines.io.parallelism

fun main(args: Array<String>) {


    class Counter {
        private var current=0
        private var max=0
        fun addOne() {
            synchronized(this) {
                current++
                max = Math.max(max,current)

            }
        }
        fun subOne() {
            synchronized(this) {
                current--
            }
        }
        fun getMax() = max
    }

    val counter=Counter()

    val jobs = (0..500).map {
        CoroutineScope(Dispatchers.IO).launch {
            counter.addOne()
            Thread.sleep(100)
            counter.subOne()
        }
    }
    var done = false
    while(!done) {
        val j = jobs.find{it.isActive}
        if( j == null) {
            done = true
        } else {
            Thread.sleep(100)
        }
    }

    println("max = ${counter.getMax()}")
}

【讨论】:

  • 感谢您回答我的问题。即使在我的电脑条件下,您的代码也能正常工作。我认为问题是我的代码,你能告诉我我上面的代码有什么问题吗?
  • 我没有看到你的代码有任何问题。如果您在我的代码中打印出线程名称,您也会得到 64 以上的数字。我只是认为 Dispatchers.IO 的线程命名与内部线程数无关。
  • 哦,我明白了,非常感谢!我花了很多时间来处理这个问题......现在解决了!
【解决方案2】:

根据 kotlin 官方手册的描述,由于协程的线程共享特性,在 IO dispatcher 上操作时可以创建(但不使用)超过 64 个(默认并行)线程。

请参考 https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/-i-o.html.

【讨论】:

    【解决方案3】:

    引用我自己的文章:

    Dispatcher.Default 限制了 CPU 内核的数量,而 Dispatcher.IO 有一个具有可配置最大大小的弹性线程池,预计这些线程池大部分时间都在不可运行 状态,等待 IO 操作完成。

    更多信息可以在这里找到:Kotlin Coroutines for Android - The ABC’s

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-14
      • 2021-11-12
      • 1970-01-01
      • 2021-10-01
      • 1970-01-01
      相关资源
      最近更新 更多