【问题标题】:How to execute a blocking coroutine call in kotlin and specify the thread如何在kotlin中执行阻塞协程调用并指定线程
【发布时间】:2020-01-14 05:23:25
【问题描述】:

是否可以在执行阻塞协程调用(返回值)的同时提供线程来执行调用(我不想使用默认的主线程)?

【问题讨论】:

    标签: kotlin kotlin-coroutines


    【解决方案1】:

    我想你正在寻找异步(上下文):

    import kotlinx.coroutines.*
    
    fun someCalc(): Int {
        println(Thread.currentThread().name) // Prints different thread
        Thread.sleep(500L)
        return 42
    }
    
    fun main() {
        val result = runBlocking {
            val deferred = async(Dispatchers.Default) {
                someCalc()
            }
            deferred.await()
        }
        println(result)
    }
    

    您还可以使用 newSingleThreadContext() 创建一个仅限于单个线程的上下文并使用它来代替 Dispatchers.Default

    编辑:正如@Rene 所说,有一个更好的解决方案:

    val result = runBlocking {
            withContext(Dispatchers.Default) {
                someCalc()
            }
        }
    

    【讨论】:

    • withContext 会更容易。
    • 好的,但是假设我使用Thread() 创建了一个线程,我将如何使用此方法在该特定线程上执行调用?
    • 你做不到(除非你自己写调度器)。您可以做的是创建自己的 ExecutorService 绑定到单个线程,因此该线程既可以由协程使用,也可以在您的程序中使用。 val executor = Executors.newSingleThreadExecutor() val context = executor.asCoroutineDispatcher() 然后使用 withContext(context) 启动协程并使用 executor.execute() 启动您想在此线程中启动的任何代码。
    • 当你创建一个线程时,你应该传递一个Runnable,它将在这个线程中执行。这个Runnable构造后你不能改变,所以Thread必须由ExecutorService或Dispatcher来构造和封装,而不是你。
    【解决方案2】:

    如果您只有一个已经在运行的线程,并且您无法控制它运行的代码,那么您将无能为力。线程必须运行顶级事件循环,以便您可以注入代码以从外部运行。

    如果您有这种控制权,或者您可以决定线程将从哪个Runnable 开始运行,这里有一些相当老套的代码,它设法设置一个事件循环并提交一个协程到它:

    val myContextFuture = CompletableFuture<CoroutineContext>()
    thread(name = "my-thread") {
        runBlocking {
            myContextFuture.complete(coroutineContext)
            coroutineContext[Job]!!.join()
        }
    }
    val myContext = myContextFuture.get()
    

    这是在 myContext 上运行协程的方法:

    val result = withContext(myContext) {
        println("Running on thread ${currentThread().name}")
        3
    }
    println("Result of the coroutine: $result")
    

    我不建议在生产中使用这种代码。

    【讨论】:

      猜你喜欢
      • 2020-05-21
      • 1970-01-01
      • 2021-01-26
      • 1970-01-01
      • 2019-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多