NIO 和 IO 的对比
IO 和 NIO 的区别主要体现在三个方面:
IO 基于流(Stream oriented), 而 NIO 基于 Buffer (Buffer oriented)
IO 操作是阻塞的, 而 NIO 操作是非阻塞的
IO 没有 selector 概念, 而 NIO 有 selector 概念.
Buffer
1、mark:初始值为-1,用于备份当前的position;
2、position:初始值为0,position表示当前可以写入或读取数据的位置,当写入或读取一个数据后,position向前移动到下一个位置;
3、limit:写模式下,limit表示最多能往Buffer里写多少数据,等于capacity值;读模式下,limit表示最多可以读取多少数据。
4、capacity:缓存数组大小
Channel
NIO把它支持的I/O对象抽象为Channel,Channel又称“通道”,类似于原I/O中的流(Stream),但有所区别:
1、流是单向的,通道是双向的,可读可写。
2、流读写是阻塞的,通道可以异步读写。
3、流中的数据可以选择性的先读到缓存中,通道的数据总是要先读到一个缓存中,或从缓存中写入,如下所示:
Selector
这里出来一个新概念,selector,具体是一个什么样的东西?
想想一个场景:在一个养鸡场,有这么一个人,每天的工作就是不停检查几个特殊的鸡笼,如果有鸡进来,有鸡出去,有鸡生蛋,有鸡生病等等,就把相应的情况记录下来,如果鸡场的负责人想知道情况,只需要询问那个人即可。
在这里,这个人就相当Selector,每个鸡笼相当于一个SocketChannel,每个线程通过一个Selector可以管理多个SocketChannel。
为了实现Selector管理多个SocketChannel,必须将具体的SocketChannel对象注册到Selector,并声明需要监听的事件(这样Selector才知道需要记录什么数据),一共有4种事件:
1、connect:客户端连接服务端事件,对应值为SelectionKey.OP_CONNECT(8)
2、accept:服务端接收客户端连接事件,对应值为SelectionKey.OP_ACCEPT(16)
3、read:读事件,对应值为SelectionKey.OP_READ(1)
4、write:写事件,对应值为SelectionKey.OP_WRITE(4)
这个很好理解,每次请求到达服务器,都是从connect开始,connect成功后,服务端开始准备accept,准备就绪,开始读数据,并处理,最后写回数据返回。
所以,当SocketChannel有对应的事件发生时,Selector都可以观察到,并进行相应的处理。
网友评论