09-阻塞与挂起
12.3.3 阻塞与挂起
通常,线程阻塞的代价是异常昂贵的,尤其是在高负载状态下,可用线程很少,阻塞其中一个线程就可能会导致一些重要线程被延迟。而协程挂起几乎无代价,不需要上下文切换或OS的任何干预,重要的是,协程挂起可以在很大程度上由用户自己控制。
与线程的另一个区别是,协程不能在随机指令中挂起。
为了更好地理解协程的阻塞和挂起操作,我们看一个简单的例子。
fun main(args: Array<String>) {
coroutineDemo()
}
fun coroutineDemo() {
launch(CommonPool) { //在CommonPool线程池中创建一个协程
delay(1000L, TimeUnit.MILLISECONDS) //协程挂起1s
println ("Hello,")
}
println("World!") //协程挂起,执行main函数
Thread.sleep (2000L) //主线程睡眠2s,协程恢复后继续执行挂起前的操作
}
运行上面的代码,输出的结果如下。
World!
Hello,
在上面的示例代码中,首先在CommonPool线程池中创建一个协程,并使用launch函数来启动协程,然后调用delay函数执行协程挂起操作并在协程挂起时执行打印操作,在协程恢复后继续执行协程挂起前的操作。在此示例中,delay函数主要用来执行协程的挂起操作,delay函数是一个特殊的挂起函数,它不会阻塞线程,而只是暂停协程的执行,它只能在协程中使用。
在上面的示例程序中,通过launch创建的协程在CommonPool线程池中,因此该协程并不运行在主线程上。如果希望直接在主线程上创建协程,则可以使用runBlocking方式。