参考
目的
- 探究nio读写何时是阻塞/非阻塞的
- 总结nio读写何时会触发
- 总结nio读写的数据是如何流动的
- rea
探究nio读写何时是阻塞/非阻塞的
参考
阻塞情况
概括NIO的阻塞情况
NIO一个重要的特点是:socket主要的读、写、注册和接收函数
- 在等待就绪阶段都是非阻塞的
- 真正的I/O操作是同步阻塞的(消耗CPU但性能非常高)。
举例比较BIO, NIO和AIO的阻塞情况
以socket.read()为例子:
- BIO中,如果TCP RecvBuffer里没有数据,函数会一直阻塞,直到收到数据,返回读到的数据。
- NIO中,如果TCP RecvBuffer有数据,就把数据从网卡读到内存,并且返回给用户;反之则直接返回0,永远不会阻塞。
- AIO中, 不但等待就绪是非阻塞的,就连数据从网卡到内存的过程也是异步的。
优化线程模型
根据NIO的阻塞特征, 以及结合Reactor模型, 我们可以提出以下线程模型:


仔细分析一下我们需要的线程,其实主要包括以下几种:
- 事件分发器,单线程选择就绪的事件。
- I/O处理器,包括connect、read、write等,这种纯CPU操作,一般开启CPU核心个线程就可以。
- 业务线程,在处理完I/O后,业务一般还会有自己的业务逻辑,有的还会有其他的阻塞I/O,如DB操作,RPC等。只要有阻塞,就需要单独的线程。
由上图2可知, java Charset一般用于创建编码/解码对象, 对输入输出流进行编解码.
简单概括, 凡会造成阻塞的一类行为, 我们都可以分配一组线程去处理. 我们可以为三种事件都分配相应的线程处理.
总结nio读写何时会触发
参考
首先, java nio是水平触发
其次, 水平触发下, 事件触发条件是:
- 缓冲区未空时, 触发读操作
- 缓冲区未满时, 触发写操作
Linux epoll的水平触发是以缓冲区空满状态来判断的。
缓冲区指什么呢?(应该是sendqueue和recvqueue吧)
网友评论