kotlin: yield()的用途

一,例子:不用yield()挂起当前任务

说明:yield在协程中就可以简单的理解为,
挂起当前任务(注意是任务),
释放此线程的monitor让其他正在等待的任务公平的竞争,去获得执行权。

代码:

定义线程和函数

val singleDispatcher = newSingleThreadContext("Single")
suspend fun printSomeThingSleep(text: String) {
    println(text)
    Thread.sleep(1000)
}
suspend fun printSomeThingDelay(text: String) {
    println(text)
    delay(1000)
}

代码:

        //处理按钮点击事件
        binding.button1.setOnClickListener {
            runBlocking {
                val job = GlobalScope.launch {
                    launch {
                        withContext(singleDispatcher) {
                            repeat(3) {
                                printSomeThingSleep("Task1")
                            }
                        }
                    }

                    launch {
                        withContext(singleDispatcher) {
                            repeat(3) {
                                printSomeThingSleep("Task2")
                            }
                        }
                    }
                }
                job.join()
            }
        }

运行结果:

image

在同一个线程中,一个协程运行时,不交出cpu时间,则另一个协程就得不到执行,
Thread.sleep不会挂起任务
所以这里两个协程是顺序执行的。

二,例子:改为用yield()挂起当前任务

代码:

      //处理按钮点击事件
        binding.button2.setOnClickListener {
            runBlocking {
                val job = GlobalScope.launch {
                    launch {
                        withContext(singleDispatcher) {
                            repeat(3) {
                                printSomeThingSleep("Task1")
                                yield()
                            }
                        }
                    }

                    launch {
                        withContext(singleDispatcher) {
                            repeat(3) {
                                printSomeThingSleep("Task2")
                                yield()
                            }
                        }
                    }
                }
                job.join()
            }
        }

运行结果:

image

两个协程用yield轮流挂起,交出执行权,所以两个协程交替各执行一次循环到结束

三,例子:改为用delay()挂起当前任务

代码:

        //处理按钮点击事件
        binding.button3.setOnClickListener {
            runBlocking {
                val job = GlobalScope.launch {
                    launch {
                        withContext(singleDispatcher) {
                            repeat(3) {
                                printSomeThingDelay("Task1")
                            }
                        }
                    }

                    launch {
                        withContext(singleDispatcher) {
                            repeat(3) {
                                printSomeThingDelay("Task2")
                            }
                        }
                    }
                }
                job.join()
            }
        }

运行结果:

image

这里不用yield,而是使用delay,起到了相同的效果,
delay()函数会挂起自身,这样其他的协程就可以执行了

 

posted @ 2025-08-09 13:41  刘宏缔的架构森林  阅读(21)  评论(0)    收藏  举报