1.前言
什么是 BIO、NIO、AIO ,不难看出,都是共同的字符IO ,
IO的意思是input output ,即输入输出 ,
那么 B 、 N 、A 分别指不同的io模型 ,而io又分为 文件io、socket通信io 等
2.什么意思?
BIO 是同步阻塞io模型,
NIO是同步非阻塞io模型,
AIO是异步非阻塞io模型。
3.该怎么理解?
(1)BIO ,同步阻塞io模型, 每当发起一个io操作,系统就会生成一个单独的线程来对其处理,此时需要等该线程处理结束返回结果后才可以做其他操作,
期间会卡在哪里;缺点是高并发操作会导致线程创建暴增,当线程数上涨到极限,会导致系统崩溃。
于是出现了一个叫做伪异步BIO的东西 ,也被称为M:N客户服务模型,其实就是在里面使用了线程池和任务队列,而减少线程的创建数量,提高线程利用率,增加服务器的处理能力。底层其实仍然是1对1的处理同步阻塞模式,只是增加了线程池,后来的请求需要等待进入任务队列排队,等待活跃线程来处理。
(2)NIO,同步非阻塞io模型 ,增加了管道【channel】和选择器[selector]的概念 , 需要做io操作时,对管道进行操作,内存于管道之间需要一个缓冲区buffer作为中间容器操作,一般是 字节buffer 【ByteBuffer】 ,然后管道对buffer进行读【read(buffer)】或写【write(buffer)】操作,
文件管道【FileChannel】不使用选择器,只有在socket io 才使用选择器 。
选择器其实是使用一个线程,做多路复用机制 ,其实就是一直循环,做轮询操作。
与管道做完io操作后,会将这个管道注册到选择器里面,并设置该管道的属性会对某个事件感兴趣,
一共有4种事件【
//
//SelectionKey.OP_CONNECT ——连接就绪事件,表示客户与服务器的连接已经建立成功,同通知服务端回应我
channel.register(selector, SelectionKey.OP_CONNECT);
//
//SelectionKey.OP_READ —— 读就绪事件,表示通道中已经有了可读的数据,可以执行读操作了(通道目前有数据,可以进行读操作了
channel.register(selector, SelectionKey.OP_READ);
//
//SelectionKey.OP_WRITE —— 写就绪事件,表示已经可以向通道写数据了(通道目前可以用于写操作,通知自己的选择器触发写事件)
channel.register(selector, SelectionKey.OP_WRITE);
//
//SelectionKey.OP_ACCEPT—— 接收连接就绪事件,表示准备好接收客户端的连接请求啦
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
】
nio虽然是同步,但不是阻塞,也就是说,由通道向选择器注册一个事件后,就可以去干其他事情了,不会卡死,但是还需要时不时的看一下有没有结果返回来
【也就是客户端的选择器遍历操作】
(3)AIO,是异步非阻塞io模型,当客户端发出请求时,系统接收请求后完全由系统处理,客户端可以去干其他事,同时也不需要关系结果是什么时候处理好,
等系统把结果处理好后,由系统通知客户端获取结果即可。类似于前端Ajax请求。
【猜测websocket就是使用 AIO模型做的,因为没有轮询操作,轮询操作是BIO的典型特征】