前述
同步异步,阻塞非阻塞是一些非常常见的概念,但是对于开发者来说往往是用到了很难说清楚。
笔者专门整理了下这方面的概念,作此文以记之。
这部分内容可能存在一些争议,如有不同意见欢迎评论交流。
概念
个人理解同步异步与阻塞非阻塞最好的区分是从描述对象上:
- 同步异步:用于描述任务、事件或者行为。
- 阻塞非阻塞:用于描述线程或者进程是否会被挂起。
同步
一个任务调起另一个任务的时候,会去等待其任务返回结果(或执行结束),然后再继续执行。
如下两图都是同步操作:
在Task A调用Task B后,Task A会等待Task B执行结束后,再继续执行。
异步
一个任务调起另一个任务的时候,不会去等待其返回结果(或执行结束),仍然继续执行自己的逻辑。
如下图,在Task A调用Task B后,Task A不会停止执行,Task A与Task B并行执行。
阻塞
是指调用结果返回之前,当前线程(进程)会被挂起。
在调用的结果返回之前,当前线程(进程)不会执行其他操作。
如下图:
非阻塞
指执行一个调用,当前线程(进程)不会挂起。
当前线程(进程)如果还有其他操作,不会影响执行。
如下图:
例子
同步异步与阻塞非阻塞,不是非此即彼的概念。
读者肯定可以发现上面的概念中,两者的例图都已经有了重复的情况。
后面的篇幅就展示四个例子,便于读者用作区分:
- 同步阻塞
- 同步非阻塞
- 异步非阻塞
“异步阻塞”笔者没有想到相关的场景,如有读者有相关见解的欢迎评论沟通。
个人理解,异步行为下,Task是不会去等待其他Task的结果的,那么阻塞就没有意义,因此这种场景非常少见。
(如果同时存在2个以上的Task,“异步非阻塞”和“同步阻塞”并存的场景还是有的,但是这也不能称为“异步阻塞”。)
同步阻塞
TASK A 等待Task B执行结束后才继续执行,因此是一个同步操作。
TASK A 在Thread One中调用Task B的时候,Thread One挂起等待Task B的返回结果,因此是阻塞。
同步非阻塞
TASK A 等待Task B执行结束后才继续执行,因此是一个同步操作。
TASK A 和Task B在同一个线程,没有存在挂起线程的情况,因此是非阻塞。
异步非阻塞
TASK A在执行过程中调起了Task B,与Task B并行执行,因此是异步。
Task A调起Task B后,并没有挂起当前线程,因此是非阻塞。