不阻塞线程

阻塞线程 = 线程被"钉死"在原地,干瞪眼等着,别的啥也干不了

不阻塞线程 = 线程标记一下"这事我记着,先去干别的",等条件满足了再回来继续


用餐厅服务员类比

假设一个服务员(线程)要服务两桌客人:

阻塞(Blocking)

服务员给A桌下单后,站在收银台前一动不动,盯着出餐口等菜做好。B桌客人喊破喉咙他也听不见,因为他人被"卡"在这了。

kotlin

复制代码
// 阻塞线程:线程干等着,啥也不干
fun fetchData(): String {
    val response = httpClient.execute(request)  // 线程卡在这里等网络响应
    // 网络没回来之前,这行代码下面的都执行不了
    return response.body
}

不阻塞 / 挂起(Non-blocking / Suspend)

服务员给A桌下单后,记在小本上,转身去给B桌点菜、给C桌加水。后厨喊"A桌好了",他再回来端菜。

kotlin

复制代码
// 挂起协程:线程被释放,可以去执行其他协程
suspend fun fetchData(): String {
    val response = httpClient.executeAsync(request).await()  // 协程挂起
    // 等待期间,线程去执行别的协程任务了
    return response.body
}

代码层面的区别

表格

阻塞线程 不阻塞线程(挂起)
线程状态 RUNNABLE 但卡在等待,CPU 空转或内核挂起 协程挂起,线程被释放去执行别的任务
资源占用 占着线程不干活 线程可以服务其他协程
代码写法 直接调用函数 需要 suspend + await
并发能力 1个线程只能做1件事 1个线程可以同时"跟进"上百个协程

一个更直观的对比

kotlin

复制代码
// ========== 阻塞线程 ==========
fun blockingWay() {
    val result1 = fetchFromNetwork()  // 耗时2秒,线程卡死2秒
    val result2 = fetchFromNetwork()  // 再卡2秒
    // 总共4秒,线程全程被占着
}

// ========== 不阻塞线程 ==========
suspend fun nonBlockingWay() = coroutineScope {
    val deferred1 = async { fetchFromNetworkAsync() }  // 启动,不等待
    val deferred2 = async { fetchFromNetworkAsync() }  // 立刻启动第二个
    
    val result1 = deferred1.await()  // 如果需要,这里挂起协程(不是线程)
    val result2 = deferred2.await()
    // 两个请求同时发,大约2秒完成,等待期间线程去干别的了
}

一句话总结

阻塞线程 是"人(线程)被活拴在一件事上,别的干不了";

不阻塞线程是"事(协程)被挂起来记着,人(线程)先去忙别的,回头再来"。

协程的 await 挂起的是协程 ,释放的是线程。这是它能用少量线程处理大量并发请求的根本原因。

相关推荐
北京自在科技13 小时前
谷歌 Find Hub 迎来新版本更新
android·安卓
古法安卓19 小时前
Android-休眠唤醒后onLocationChanged没有数据问题排查
android·java·android studio
Htr_1 天前
Creem 2.0 使用指南:面向 AI 构建时代的资金平台
android·数据库·人工智能·ui·photoshop
wardenlzr1 天前
车机看门狗(Watchdog)为何会让整机硬重启
android·优化·车机
IT毕设实战小研1 天前
基于大数据的商场商铺数据分析与可视化的设计与实现
android·java·大数据·django·课程设计
aqi001 天前
一文读懂 HarmonyOS 7.0 带来的十大API重要升级
android·华为·harmonyos·鸿蒙·harmony
是店小二呀1 天前
鸿蒙PC开源移植:CodeLite原生IDE与Remote Agent适配
android·智能手机·远程桌面
不要喷香水1 天前
00-总览与架构
kotlin·app·档案管理
终端安全笔记1 天前
iOS 27 给了租赁一个新工具,但它只认受监督的设备
android·网络·安全·ios