阻塞、非阻塞,同步、异步是我们经常说的概念,但是实际上我们经常是把这些概念搞混的。今天详细的记录一下:
总结来说,在 Unix IO 模型的语境下:同步和异步的区别:数据拷贝阶段是否需要完全由操作系统处理。阻塞和非阻塞操作:是针对发起 IO 请求操作后,是否有立刻返回一个标志信息而不让请求线程等待(cpu可以处理其他请求)。因此,Java NIO 是同步且非阻塞的 IO 。

BIO、NIO 有什么区别?

线程模型不同 BIO:一个连接一个线程,客户端有连接请求时服务器端就需要启动一个线程进行处理。所以,线程开销大。可改良为用线程池的方式代替新创建线程,被称为伪异步 IO 。NIO:一个请求一个线程,但客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到连接有新的 I/O 请求时,才启动一个线程进行处理。可改良为一个线程处理多个请求,基于 多 Reactor 模型。BIO 是面向流( Stream )的,而 NIO 是面向缓冲区( Buffer )的。BIO 的各种操作是阻塞的,而 NIO 的各种操作是非阻塞的。BIO 的 Socket 是单向的,而 NIO 的 Channel 是双向的。可能文字比较难记,整理出来就是下图:

有一点要注意,虽然图中说 NIO 的性能一般,但是在绝大多数我们日常业务场景,NIO 和 AIO 的性能差距实际没这么大。在 Netty5 中,基于 AIO 改造和支持,最后发现,性能并没有想象中这么强悍,所以 Netty5 被废弃,而是继续保持 Netty4 为主版本,使用 NIO 为主。为了胖友能更好的记住和理解 BIO、NIO、AIO 的流程,胖友可以在理解下图: