- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
想了解一下kotlin协程的执行顺序和线程切换。我用了withContext
切换到另一个上下文并运行耗时的任务,因此主线程不会被阻塞。但是 kotlin 并没有像预期的那样切换上下文。
代码在 kotlin 操场上运行:https://pl.kotl.in/V0lbCU25K
不起作用的情况
suspend fun main() = runBlocking {
println("Hello, world!!!")
println(Thread.currentThread().name)
withContext(Dispatchers.IO) {
println("Before heavy load: ${Thread.currentThread().name}")
Thread.sleep(5000)
println("After heavy load: ${Thread.currentThread().name}")
}
println("waiting")
println(Thread.currentThread().name)
}
Hello, world!!!
main @coroutine#1
Before heavy load: DefaultDispatcher-worker-1 @coroutine#1
After heavy load: DefaultDispatcher-worker-1 @coroutine#1
waiting
main @coroutine#1
sleep
上述代码块中的函数在与主线程相同的线程中运行并阻塞它。
suspend fun main() = runBlocking {
println("Hello, world!!!")
println(Thread.currentThread().name)
launch {
println("Before heavy load: ${Thread.currentThread().name}")
Thread.sleep(5000)
println("After heavy load: ${Thread.currentThread().name}")
}
println("waiting")
println(Thread.currentThread().name)
}
Hello, world!!!
main @coroutine#1
waiting
main @coroutine#1
Before heavy load: main @coroutine#2
After heavy load: main @coroutine#2
suspend fun main() = runBlocking {
println("Hello, world!!!")
println(Thread.currentThread().name)
launch {
withContext(Dispatchers.IO) {
println("Before heavy load: ${Thread.currentThread().name}")
Thread.sleep(5000)
println("After heavy load: ${Thread.currentThread().name}")
}
}
println("waiting")
println(Thread.currentThread().name)
}
Hello, world!!!
main @coroutine#1
waiting
main @coroutine#1
Before heavy load: DefaultDispatcher-worker-1 @coroutine#2
After heavy load: DefaultDispatcher-worker-1 @coroutine#2
最佳答案
I used
withContext
to switch to another context and run time consuming tasks, so the main thread won't be blocked. But kotlin did not switch context as expected.
withContext
call 确实释放了主线程。它将工作转移到另一个线程,但此时您的主线程无事可做,只能等待
withContext
调用完成。
runBlocking
启动一个事件循环,它可以为任意数量的并发协程提供服务,但由于您只有一个,因此必须完成一个协程才能获得
runBlocking
block 完成。
fun main() {
measureTimeMillis {
runBlocking {
launchManyCoroutines()
println("Top-level coroutine sleeping on thread ${currentThread().name}")
delay(2_000)
println("Top-level coroutine done")
}
}.also { println("Program done in $it milliseconds") }
}
private fun CoroutineScope.launchManyCoroutines() {
val cpuCount = getRuntime().availableProcessors()
(1 until cpuCount).forEach { coroId ->
launch { // on the main thread
val sum = withContext(Dispatchers.Default) {
println("Coroutine #$coroId computing on thread ${currentThread().name}")
computeResult()
}
println("Coroutine #$coroId done on thread ${currentThread().name}:" +
" sum = $sum")
}
}
(cpuCount + 1..100).forEach { coroId ->
launch { // on the main thread
println("Coroutine $coroId sleeping 1 s on thread ${currentThread().name}")
delay(1_000)
println("Coroutine #$coroId done on thread ${currentThread().name}")
}
}
}
private fun computeResult(): Int {
val rnd = ThreadLocalRandom.current()
return (1..1_000_000).map { rnd.nextInt() }.sum()
}
withContext(Dispatchers.Default)
在线程池上执行 CPU 密集型任务(总计一百万个随机整数),而其他任务则直接在主线程上执行暂停工作(延迟一秒)。最后,顶级协程在完成前休眠 2 秒。
Top-level coroutine sleeping on thread main
Coroutine #2 computing on thread DefaultDispatcher-worker-2
Coroutine #3 computing on thread DefaultDispatcher-worker-3
Coroutine #4 computing on thread DefaultDispatcher-worker-5
Coroutine #1 computing on thread DefaultDispatcher-worker-1
Coroutine #5 computing on thread DefaultDispatcher-worker-6
Coroutine #6 computing on thread DefaultDispatcher-worker-4
Coroutine #7 computing on thread DefaultDispatcher-worker-8
Coroutine 9 sleeping 1 s on thread main
Coroutine 10 sleeping 1 s on thread main
...
Coroutine 99 sleeping 1 s on thread main
Coroutine 100 sleeping 1 s on thread main
Coroutine #3 done on thread main: sum = -1248358970
Coroutine #4 done on thread main: sum = -228252033
Coroutine #6 done on thread main: sum = -147126590
Coroutine #2 done on thread main: sum = -1065374439
Coroutine #1 done on thread main: sum = -2029316381
Coroutine #7 done on thread main: sum = -865387844
Coroutine #5 done on thread main: sum = -1695642504
Coroutine #9 done on thread main
Coroutine #10 done on thread main
...
Coroutine #99 done on thread main
Coroutine #100 done on thread main
Top-level coroutine done
Program done in 2066 milliseconds
关于multithreading - 为什么 'withContext' 不切换 'runBlocking' 下的协程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58794816/
我正在尝试根据 repo 调用的响应数据运行一个函数,并遇到竞争条件/使用协程范围返回数据的问题。基于这两个伪代码块,我想知道是否可以得到一些帮助? 选项 1:如果不使用 runBlocking,则无
我正在尝试创建一个基本的生成序列 - 必须创建 block ,moveDownLeft,然后是 removeLeft。当之前使用 self.addChild(block1) 添加 block 时,mo
抱歉,对 swift 还很陌生,而且一般都是编码,所以这可能是一个初学者问题。我目前有下面的代码围绕一个圆圈创建箭头。我如何转换它以便所有箭头都在最后一个箭头后 1 秒生成,直到它们全部创建?另一个线
这是我的代码: ship.runAction(SKAction.waitForDuration(5), completion: { self.ship.flyStraight()//retai
我在 Kotlin 中的 await 有问题,如果我只使用 2 个 awaits,这个 runBlocking block 可以工作 10 秒,但是当我尝试使用 4 个 awaits,它工作20秒。据
编辑 2:我想我误解了文档。我读: runBlocking This function should not be used from a coroutine. It is designed to b
我想了解 kotlin 中的 runBlocking。 println("before runBlocking ${Thread.currentThread().name}") runBlo
我正在尝试理解协程,但似乎比预期的更难理解,也许有人可以给我正确的方法。 我想要一个端点(简单的 hello world)来调用挂起的函数。 为此,我做了这个: @GET @Path("/test")
来自 the documentation of runBlocking 是否清楚为什么从协程中使用它没有意义,例如嵌套它。 它甚至明确指出: This function should not be u
let randomize = SKAction.runBlock({ [unowned self] in self.footstepFile = "Content/foots
我有几个需要按顺序运行的 runBlock,但即使在使用 SKAction.sequence([action1, action2, action3]) 时发现它们仍然同时运行。任何帮助将不胜感激。 这
我对 Swift 还很陌生。我试图永远运行一段动画代码。我在这里做错了什么?它一直提示“调用中缺少完成参数”。 func randomCGFloat() -> CGFloat { var te
我是 Swift 的新手,但我在类和继承方面遇到了麻烦。我有一个名为 Bunny 的类,其中包含一些代码,包括 SKAction。当我将在 Bunny 中找到的代码放入我的 GameScene 类时,
如何停止 runBlock 的所有操作: func slideShowControl () { let noObject = SKSpriteNode() noObject.name
这是我正在玩的 SpriteKit 测试应用程序中的一些简单代码: let wait = SKAction.waitForDuration(1) let perform = SKAction.runB
我一直在尝试在我的游戏中实现以下功能。我在 sprite 节点上运行一个 Action (sprite 节点父级为 nil),该 Action 应该等待我指定的时间,然后将节点添加到 self。我找不
我正在学习 Kotlin 协程。我读过 runBlocking 是桥接同步和异步代码的方法。但是如果 runBlocking 停止 UI 线程,性能提升是多少?比如我需要在Android中查询一个数据
MainCoroutineRule和 runBlocking Kotlin Coroutines 都是为测试目的而设计的。似乎两者都提供相同的功能:在测试环境中同步运行代码。 那么有什么区别呢?他们每
Kotlin 的 runBlocking Coroutine 应该阻塞当前线程,直到块内的 Coroutine 完成执行,但是当块内的 Coroutine 是 GlobalScope.launch 时
I have switched my context to Dispatcher.Main to show UI but data fetched on runBlocking but unable
我是一名优秀的程序员,十分优秀!