线程阻塞调用与同步调用的区别

一、核心

  • 同步调用:调用方必须等被调用方"完成"后才能继续执行。

  • 线程阻塞调用:调用方在等待结果时,线程被挂起(不占用 CPU),直到条件满足再被唤醒。

也就是说:

同步调用关注"调用方式",线程阻塞关注"线程状态"。

二、它们不是同一个维度的概念

你可以把它们理解成:

  • 同步 / 异步:描述"调用方是否需要等待结果"。

  • 阻塞 / 非阻塞:描述"等待时线程是否被挂起"。

因此会出现四种组合:

  1. 同步阻塞(最常见)

例:Java 的 Thread.sleep() 、 Object.wait() 、 Socket.accept()

  1. 同步非阻塞

例:轮询一个标志位,线程不挂起但一直检查。

  1. 异步阻塞(很少见)

例:异步回调在另一个线程执行,但主线程调用 Future.get() 阻塞等待结果。

  1. 异步非阻塞(高性能网络常用)

例:Netty、NIO、JavaScript Promise、Go 的 goroutine + channel。

三、用生活例子快速理解

你去咖啡店点咖啡:

  1. 同步调用

你点完单后,必须等咖啡做好才能离开柜台。

  1. 线程阻塞调用

你点完单后,店员让你"坐着等叫号",你不需要一直站在柜台前,但你也不能去做别的事,只能等。

  1. 异步调用

你点完单后,店员给你一个取餐码,你可以去逛街,等咖啡好了再回来取。

  1. 非阻塞

你不等店员叫号,自己每隔几秒去柜台看一下"好了没"。

四、技术层面的更细解释

同步调用的特点

  • 调用方和被调用方在同一个执行流程中。

  • 调用方必须等待被调用方返回。

  • 是否阻塞取决于实现。

例:

java

int result = add(1, 2);

System.out.println(result); // 必须等 add 返回

线程阻塞调用的特点

  • 线程由操作系统挂起(进入 BLOCKED/WAITING 状态)。

  • 不占用 CPU。

  • 通常发生在等待 I/O、锁、条件变量、睡眠等场景。

例:

java

synchronized (lock) {

lock.wait(); // 当前线程阻塞,直到被 notify

}

五、为什么很多人会混淆?

因为大多数同步调用在底层实现上都会阻塞线程,所以大家会把"同步"和"阻塞"当成同义词。

但它们本质不同。

例如:

  • 同步但不阻塞:

你循环检查一个变量,不挂起线程。

  • 异步但阻塞:

你发起一个异步任务,但你立刻调用 future.get() 阻塞等待结果。

相关推荐
chlk12314 小时前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑15 小时前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件15 小时前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
深紫色的三北六号1 天前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash1 天前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI2 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行2 天前
Linux和window共享文件夹
linux
木心月转码ing3 天前
WSL+Cpp开发环境配置
linux
崔小汤呀4 天前
最全的docker安装笔记,包含CentOS和Ubuntu
linux·后端
何中应4 天前
vi编辑器使用
linux·后端·操作系统