文章目录
0.前言
本文讲的IO模型主要是讲的是网络IO模型,而且编程语言使用的是Java语言。对于网络IO,个人觉得最重要一点是要弄清是从哪个方面来划分的。主要分成两个角度:一个是操作系统的角度,一个是Java语言的角度。
网上很多博客没有说清楚划分角度,只是从某一个角度出发,初学时吃了不少苦头,因为不同角度的IO模型,有些知识是冲突的。大概划分入下图:
操作系统层面的IO是底层IO,Java语言层面的是对它进行了一个封装,BIO用的是阻塞IO,NIO底层用的是多路复用,AIO是异步IO。其实这样看也还可以接受,但NIO也叫同步非阻塞IO,这个可能就会引起歧义,但它的底层使用的是多路复用IO,下面将会细讲到。
1. 两对基本概念
IO在发生的时候,涉及到了两个对象:
- 一个是调用这个IO的任务对象(线程或者进程)
- 一个是系统内核(可以说成操作系统)
IO所有模型的不同,就发生在这两个对象上,且这两个对象也分别对应了以下两个概念:
- 任务对象对应了阻塞与非阻塞
- 系统内核对应了同步和异步
如上图,这里就模拟了一次IO的过程,简单来说就是客户端发来请求,服务端根据请求做出响应。而阻塞非阻塞,同步异步就是针对于线程和系统内核做出响应方式的不同。
1.1 阻塞与非阻塞
阻塞与非阻塞对应的是任务对象(对应图里的线程)。我们来假设一个场景,客户端发来了一个请求,线程接收到了,然后发送给服务器端,但这个对于这个请求的处理并不是马上完成的,是需要一定时间才能得到处理结果的。那这个时候线程该怎么办呢?有两种处理方式:
- 线程进行等待,直到获得处理结果再返回客户端
- 线程不进行等待,直接返回客户端
这两种处理方式,就分别对应了阻塞与非阻塞。