【发布时间】:2020-01-14 05:23:25
【问题描述】:
是否可以在执行阻塞协程调用(返回值)的同时提供线程来执行调用(我不想使用默认的主线程)?
【问题讨论】:
是否可以在执行阻塞协程调用(返回值)的同时提供线程来执行调用(我不想使用默认的主线程)?
【问题讨论】:
我想你正在寻找异步(上下文):
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()
}
}
【讨论】:
Thread() 创建了一个线程,我将如何使用此方法在该特定线程上执行调用?
val executor = Executors.newSingleThreadExecutor() val context = executor.asCoroutineDispatcher() 然后使用 withContext(context) 启动协程并使用 executor.execute() 启动您想在此线程中启动的任何代码。
如果您只有一个已经在运行的线程,并且您无法控制它运行的代码,那么您将无能为力。线程必须运行顶级事件循环,以便您可以注入代码以从外部运行。
如果您有这种控制权,或者您可以决定线程将从哪个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")
我不建议在生产中使用这种代码。
【讨论】: