多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] > ### `IO`模型 * 1、**阻塞式 IO`** * 客户端发起了`connect`请求,那么当前线程就会休眠,阻塞在调用处,等待服务端响应完毕,返回消息,才会继续执行下去。 ![](https://i.loli.net/2019/03/15/5c8affeddc96d.png) * 2、**非阻塞式 IO** * 客户端程序会不停地去尝试读取数据,但是不会阻塞在调用读的方法处,如果读的时候,没有读到内容,也会立即返回。 ![](https://i.loli.net/2019/03/15/5c8b00b819545.png) * 3、**IO多路复用** * 最常用的`I/O`事件通知机制就是`I/O`复用(I/O multiplexing)。Linux 环境中使用`select/poll/epoll_wait `实现`I/O`复用。 ![](https://i.loli.net/2019/03/15/5c8b01a774733.png) <br/> > ### `NIO` * 非阻塞同步 * `channel`通道,与传统`IO`中的流(Stream)类似,但通道是双向的,而`Stream`是单向的,输入流只负责输入,输出流只负责输出。唯一能与通道交互的组件是缓冲器(Buffer),通过通道,可以从缓冲器中读写数据。用户可以通过选择器`Selector`管理通道`Channel`,如可在一个选择器上注册多个通道,然后通过这个选择器来管理多个通道的读写操作。 * `Buffer`缓冲器 * `Selector`选择器 <br/> > ### `IO`与`NIO`的区别 * `IO`是面向流`Stream`,`NIO`是面向缓冲区`Buffer`。 * | BIO | NIO | | --- | --- | |一个连接对应一个线程|一个连接的有效请求对应一个线程| | `IO`面向流(Stream),只能顺序的从流中读取数据,如果想跳跃性的读取或再读取已经读过的内容,就必须把流中读到的数据缓存起来| `NIO`面向缓存(Buffer),而不是面向流操作,所以可以跳跃读取或者反复读取 ||| | | `IO`是阻塞的,如调用`InputStreram.read()`方法时,它会一直等到数据到来时(或超时)才会继续执行后续代码,否则就会一直等待| 读写操作具有非阻塞性,如从某通道读取数据时,仅能得到当前可用数据,如果当前没有数据,就什么都不会读取,而且代码能继续执行。非阻塞写也是如此。 | | `NIO`的`selectors`组件允许一个线程(即一个Java类)监控多个来源(channels),也就是说通过一个线程管理多个输入和输出通道。 <br/> <br/> *** 参考: [Java NIO系列教程(一) Java NIO 概述](https://www.cnblogs.com/duanxz/p/6759689.html) [BIO与NIO、AIO的区别](https://blog.csdn.net/skiof007/article/details/52873421) [如何学习Java的NIO](https://www.zhihu.com/question/29005375/answer/184849551) [NIO原理详解](https://blog.csdn.net/charjay_lin/article/details/81810922)