为什么runBlocking未阻塞当前线程?线程状态为RUNNABLE的原因
为什么runBlocking阻塞线程时,线程状态还是RUNNABLE而非BLOCKED?
根据官方文档描述,runBlocking会启动一个新协程并阻塞当前线程直至其完成,但运行以下代码时:
fun main() { println("Before runBlocking ${Thread.currentThread().state}") runBlocking { println("After runBlocking ${Thread.currentThread().state}") } }
输出结果却是:
Before runBlocking RUNNABLE After runBlocking RUNNABLE
这是因为这里的两个"阻塞"概念完全不同:
- 线程的BLOCKED状态:是操作系统层面的线程状态,指线程因等待获取对象锁(比如进入
synchronized块)而被挂起,此时线程不会被CPU调度执行。 - runBlocking的"阻塞"语义:是协程框架层面的逻辑阻塞。
runBlocking会将当前线程转换为协程的EventLoop调度器,线程并不会被操作系统挂起,而是进入一个主动循环,持续处理协程队列中的任务,直到所有子协程执行完毕。
简单来说,runBlocking并没有让线程进入操作系统级别的阻塞状态,线程一直在运行协程调度的循环逻辑,因此线程状态始终是RUNNABLE。
如果想直观看到线程进入BLOCKED状态,可以尝试让线程等待锁,比如:
val lock = Object() fun main() { Thread { synchronized(lock) { Thread.sleep(1000) } }.start() Thread.sleep(100) // 确保另一个线程先拿到锁 println("Before sync ${Thread.currentThread().state}") synchronized(lock) {} println("After sync ${Thread.currentThread().state}") }
此时输出会显示线程进入BLOCKED状态,这才是操作系统定义的线程阻塞。
内容的提问来源于stack exchange,提问作者faritowich
相关产品推荐
相关产品推荐

