Thread.sleep vs Task.sleep:一句话记住“别再阻塞线程”

一、两句话区分

API 阻塞谁 后果
Thread.sleep(forTimeInterval:) 整条线程 线程池"饿死",其他任务无法调度
Task.sleep(nanoseconds:) 当前任务 线程立刻转去跑别的任务,资源不浪费

结论:

Swift Concurrency 时代,永远用 Task.sleep,不要用 Thread.sleep。

二、为什么 Thread.sleep 这么毒?

  1. 线程池大小固定

    Swift 并发运行时默认只开 CPU 核心数条线程(M1 ≈ 8)。

  2. 你睡一条,就少一条

    Thread.sleep 让线程进入内核阻塞状态,不会被运行时回收。

  3. 四条全睡 → App 卡死

示例:

swift 复制代码
for _ in 0..<4 {
    Task {
        Thread.sleep(forTimeInterval: 10)
    }   // 4 条线程瞬间用完
}

此时所有 Task(网络、UI、动画)都排不上队,应用假死 10 秒。

三、Task.sleep 是怎么做到"不堵线程"的?

swift 复制代码
await try Task.sleep(nanoseconds: 1_000_000_000) // 1 秒

内部流程:

  1. 当前任务被挂起 → 让出线程
  2. 运行时把线程分配给其他待执行任务
  3. 1 秒后,原任务重新入队 → 任意空闲线程继续执行

→ 零线程浪费,零阻塞,零内核调用(用户态挂起)。

四、代码对比:同样"等 1 秒",效果天差地别

Thread.sleep 版(灾难)

swift 复制代码
Task {
    print("start", Date())
    Thread.sleep(forTimeInterval: 1)          // 阻塞整条线程
    print("end  ", Date())
}

Task.sleep 版(安全)

swift 复制代码
Task {
    print("start", Date())
    await try Task.sleep(nanoseconds: 1_000_000_000) // 让出线程
    print("end  ", Date())
}

并行 10 个任务:

  • Thread.sleep → 10 秒总耗时(串行)
  • Task.sleep → 约 1 秒全部完成(并发)

五、常见踩坑 QA

❓ "我就想在 Playground 里拖延一下,也不能 Thread.sleep?"

→ 用 Task.sleep 一样简单:

swift 复制代码
Task {
    await try Task.sleep(nanoseconds: 2_000_000_000)
    print("done")
}

❓ "需要主线程延迟,用哪个?"

→ 依旧 Task.sleep,它会在任意线程醒来,若需主线程再切回来:

swift 复制代码
await MainActor.run {
    // 主线程工作
}

❓ "老代码里大量 Thread.sleep 怎么批量替换?"

→ 正则 + 脚本一键迁移:

bash 复制代码
# 示例:sed -i 's/Thread.sleep(\([^)]*\))/await Task.sleep(UInt64(\1 * 1_000_000_000))/g' *.swift

六、一句话总结

"睡线程"是毒药,"睡任务"才是解药。

记住:

Swift Concurrency 世界里,看到 Thread.sleep 就改成 Task.sleep------没有任何例外。

相关推荐
songgeb2 小时前
YYImage Bug:一行之差,正常 JPEG 如何在 iOS 被读成条纹
ios·swift
fthux4 小时前
Tick Rest,一个休息提醒工具的自我修养
macos·开源·swift
Fatbobman(东坡肘子)1 天前
快速消失的硬盘容量 -- 肘子的 Swift 周报 #160
开发语言·人工智能·redis·ios·swiftui·iphone·swift
chaoahyl1 天前
WaterDiary 喝水记录 App 实战(2)· 实现喝水首页与本地保存
swift
茶底世界之下2 天前
iPhone Duo 适配实战,Awaking 踩过的 8 个坑
ios·swiftui·swift
xbzb2 天前
Swift 对象存储建环实验 + Ceilometer 计量:两个收尾服务
swift·ring·实验·ceilometer·象存储·建环
2501_916008892 天前
iOS App 图标、启动屏和多语言搭配 方法,上架前使用KXBuild一次做好 App 图标
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
2501_915918412 天前
iOS 推送通知怎么实现,从 APNs p8 密钥到 iOS 真机收到第一条推送
vscode·ios·objective-c·个人开发·swift·敏捷流程
东坡肘子2 天前
快速消失的硬盘容量 -- 肘子的 Swift 周报 #160
人工智能·swiftui·swift
2501_916007474 天前
Windows OpenSSL 生成 iOS 证书,制作 p12 与描述文件,KXBuild 签名实操
windows·vscode·ios·objective-c·个人开发·swift·敏捷流程