java nio理解
NIO介绍:
? 一个Channel实例代表一个可轮询的i/o目标,Channel能够注册一个Selector类的实例,Selector类的select()方法允许你询问“在一组信道中,哪一个当前需要服务”。Channel实现用Buffer来传递数据。Buffer抽象代表了一定容量的数据容器(本质上就是一个数组)。Channel使用的不是流来传输数据,而是用缓冲区来读取和发送数据。与流不同,缓冲区是有固定的容量。
NIO的Channel抽象主要的特征是可以配置它的阻塞行为,如:
clntChan.configureBlocking(false);
在非阻塞式的信道上调用一个方法总是会立刻返回,这种调用的返回值指标了所请求的操作完成的程度,如:
调用ServerSocketChannel.accept()方法,如果有连接请求来了,则返回一个SocketChannel,否则返回为NUll.
针对非阻塞式的信道,这些操作都会立即返回,我们必须反复调用这些操作,直到所有的I/O操作都成功完成。
?
深刻理解这句话:select() 方法用于从已经注册的信道中返回在感兴趣的I/O 操作集上准备就绪的信道总数,这是阻塞的方法
?
Selector 小结
??? 总的来说,使用 Selector 的步骤如下:
1、 创建一个 Selector 实例。
2、 将其注册到各种信道,指定每个信道上感兴趣的 I/O 操作。
3、 重复执行:
1) 调用一种 select 方法
2) 获取选取的键列表
3) 对于已选键集中的每个键。
a.? 获取信道,并从键中获取附件(如果合适的话)
b.? 确定准备就绪的操作并执行。如果是 accept 操作,将接受的信道设置为非阻塞模式,并将其与选择器注册。
c.? 如果需要,修改键的兴趣操作集
d.? 从已选键中移除键
如果选择器告诉了你什么时候 I/O 操作准备就绪,你还需要非阻塞 I/O 吗?答案是肯定的。信道在已选键集中的键并不能确保非阻塞 I/O ,因为调用了 select() 方法后,键集信息可能会过时。另外,阻塞式写操作会阻塞等待直到写完所有字节,而就绪集中的 OP_WRITE 仅表示至少有一个字节可写。实际上,只是非阻塞模式的信道才能与选择器进行注册:如果信道在阻塞模式, SelectableChannel 类的 register() 方法将抛出 IllegalBlockingModeException 异常