【问题标题】:Why doesn't Executor.asCoroutineDispatcher work like newFixedThreadPoolContext?为什么 Executor.asCoroutineDispatcher 不像 newFixedThreadPoolContext 那样工作?
【发布时间】:2018-12-19 16:28:30
【问题描述】:

我认为这两行在执行方面是等效的:

val context1 = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
val context2 = newFixedThreadPoolContext(2, "Fixed")

但是当我在下面的代码中使用“context2”时,它会按预期工作,但“context1”就像一个单独的线程。

val context1 = Executors.newFixedThreadPool(2).asCoroutineDispatcher()

repeat(4) {
    launch {
        withContext(context1) {
            Thread.sleep(2000)
        }
    }
}

context1.close()

预期:2 个线程将并行执行。代码应该在 4 秒内完成,因为有 2 个线程休眠 2 秒然后重复。

实际:只执行一个线程,“重复”串行执行,耗时8秒。

这是一个错误吗?

或者找到here的这个文档是什么意思?

如果您需要一个带有调度策略的完全独立的线程池 即基于标准 JDK 执行程序,使用以下 表达式:Executors.newFixedThreadPool().asCoroutineDispatcher()。

【问题讨论】:

  • 能否请您发布完整的示例。在您的情况下,launch 是重要的部分。 withContext 只切换线程/上下文,但没有提到并行性。函数launchCoroutineScope 中启动一个新的协程,这个范围定义了协程是否并行运行。所以我需要你方法的上下文来给你答案。
  • 你应该把你的代码改成launch(context2) { Thread.sleep(2000) }

标签: multithreading kotlin kotlinx.coroutines


【解决方案1】:

玩完完整的代码示例:

import kotlinx.coroutines.*
import java.util.concurrent.Executors

fun log(msg: String) = println("[${Thread.currentThread().name}] $msg")


fun main() = runBlocking {
    val context1 = Executors.newFixedThreadPool(2).asCoroutineDispatcher()
    val context2 = newFixedThreadPoolContext(2, "Fixed")

    repeat(4) {
        launch {
            withContext(context1) {
                log("Start sleep $it")
                Thread.sleep(2000)
                log("Finished sleep $it")
            }
        }
    }

//    context1.close()
}

我发现问题出在“context1.close()”上。如果我注释掉“context1.close()”它可以正常工作。我的猜测是“启动”调用没有阻塞,因此“context1.close()”在“withContext”在其他线程上执行之前被执行。我原以为这会导致错误,但它似乎只是让它成为一个线程。

【讨论】:

    猜你喜欢
    • 2012-05-12
    • 2011-05-13
    • 2011-06-08
    • 1970-01-01
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-12
    相关资源
    最近更新 更多