侧边栏壁纸
博主头像
Ysfun博主等级

一名热爱技术、喜欢折腾的小小程序猿

  • 累计撰写 42 篇文章
  • 累计创建 14 个标签
  • 累计收到 25 条评论

目 录CONTENT

文章目录

彻底搞清楚「同步&异步 阻塞&非阻塞」

Ysfun
2022-08-13 / 0 评论 / 1 点赞 / 193 阅读 / 1,372 字

在谈论到网络I/O时,经常会碰到几个非常容易混淆的概念:同步、异步、阻塞、非阻塞。我们来通过这篇文章彻底搞清楚这些概念!

1. 同步&异步

同步和异步关注的是消息通信机制synchronous communication / asynchronous communication),描述的是调用者,要不要主动等待调用结果,当前线程是否需要等待方法调用执行完毕

  • 同步:就是在发出一个“调用”时,在没有得到结果之前,该“调用”就不返回。换句话说,就是调用者主动等待调用结果

这就是同步:

public static void main() {
  int result = doSomeThing();
  doAnotherThing();
}

主线程调用doSomeThing()方法,会一直等待方法执行完毕并返回结果后再继续执行其他任务。

  • 异步:当一个异步过程调用发出之后,调用者不会立刻得到结果,而是在调用执行完成后被调用者通过回调或者消息机制通知调用者。

这就是异步:

public static void main() {
  new Thread(() -> {
    int result = doSomeThing();  // doSomeThing()通过回调方法将结果通知到调用者
  });
  doAnotherThing();
}

主线程创建一个新的线程来执行doSomeThing()方法,方法调用后立即返回(无需等待方法执行完毕),主线程继续执行其他任务,等doSomeThing()方法执行完毕后通过回调机制将结果通知给主线程。

关于同步和异步,举一个通俗的例子:

考虑一个情境,你打电话问书店老板有没有《分布式系统》这本书。

如果是同步机制,书店老板会说:“你稍等,我去查一下”,然后书店老板就查啊查,你也一直在等待书店老板告诉你结果。

而如果是异步机制,书店老板会说:“我去查一下,查好了我再给你回电话”,于是就挂断电话,等查好了书店老板主动打电话告诉你结果(老板这种主动电话告诉结果的方式就是“回调”)。

2. 阻塞&非阻塞

阻塞和非阻塞描述的是函数本身,在等待某一事件的结果时,是将线程挂起,还是立即返回一个未就绪的信息。换句话说,当接口数据未就绪时,线程是否会被挂起。

阻塞和非阻塞一般都是描述IO操作,比如一个读取磁盘数据的函数。

阻塞:

public int read(byte[] buffer) {
  while (磁盘未就绪) {
    // 将当前线程挂起,并让出CPU;
  }
  // 此时磁盘已就绪
  doRead()  // 真正读取数据到buffer中
  return len;  // 返回读到的字节数
}

当磁盘未就绪时,会将当前线程挂起,并让出CPU,直到磁盘准备就绪,进行数据读取操作并返回。

非阻塞:

public int read(byte[] buffer) {
  if (磁盘未就绪) {
    // 立即返回
    return -1;
  }
  // 此时磁盘已就绪
  doRead()  //真正读取数据到buffer中
  return len;  // 返回读到的字节数
}

当磁盘未就绪时,直接返回当前磁盘未就绪状态。

至于这个函数调用者采用同步还是异步的方式调用,都不影响这个函数本身是阻塞还是非阻塞的性质。

阻塞IO:应用进程请求数据,内核进程会一直阻塞直到数据准备完成后,并完成数据复制工作,最后返回结果给应用进程。

非阻塞IO:应用进程请求数据,当内核进程发现数据未准备就绪,会立即返回未就绪信息;如果内核进程发现数据已准备就绪,完成数据复制操作并返回成功结果。

关于阻塞和非阻塞,我们仍以前面打电话向书店老板询问是否有《分布式系统》这本书为例。

根据定义,我们知道阻塞和非阻塞是针对“打电话询问书籍”的这个“函数”而言,对于阻塞情况,如果老板暂时不知道有没有这本书的时候,老板会不立即回复你,而是老板自己去查,查啊查,直到找到这本书时再回复你有这本书,然后再挂断电话;而对于非阻塞,如果老板暂时不知道有没有这本书,老板也会立刻回复你“我暂时也不清楚有没有这本书”,随即挂断电话,而不会像前面那种情况一直阻塞在打电话的状态。

关于同步&异步 阻塞&非阻塞的解释,网上有很多说法,甚至很多解释都是错误了,这篇文章是我查看了许多资料并结合自己的理解写出来的,不敢保证完全是正确的,但至少在我看来是非常合理的,如果大家有什么更好的见解欢迎大家留言探讨。

1

评论区