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

一、核心

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

  • 线程阻塞调用:调用方在等待结果时,线程被挂起(不占用 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() 阻塞等待结果。

相关推荐
虚神界熊孩儿2 小时前
Linux下修改docker和harbor默认网段的方法
linux·docker·harbor
Jay Chou why did2 小时前
ARM寄存器
linux
乌日尼乐2 小时前
【Linux】iptables使用详解(RT)
linux
wdfk_prog2 小时前
[Linux]学习笔记系列 -- bits
linux·笔记·学习
Xの哲學2 小时前
Linux epoll 深度剖析: 从设计哲学到底层实现
linux·服务器·网络·算法·边缘计算
iYun在学C2 小时前
驱动程序(注册字符设备)
linux·嵌入式硬件
延延oO3 小时前
zyzyzyzyzy
linux
小白不想白a3 小时前
linux排障:服务端口被打满
linux·服务器·网络