阻塞和非阻塞
阻塞和非阻塞是在进程访问数据的时候,数据 是否准备就绪的一种处理方式,当数据没有准备好的时候。
同步和异步
基于应用程序和操作 系统处理 IO 事件采取的方式来区别:
Java NIO (non-blocking IO) 是 java1.4 之后新出的接口,BIO 和 NIO 的对比
| IO 模型 | BIO | NIO |
|---|---|---|
| 方式 | 从硬盘到内存 | 从内存到硬盘 |
| 通信 | 面向流 | 面向缓冲(多路复用) |
| 处理 | 阻塞 IO(多线程) | |
| 出发 | 无 | 选择器(轮询机制) |
本质上是一个数组,但是缓冲区对象内置了一些机制,能够追踪和记录缓存区的状态变化, 比如我们在使用 get 方法获取数据或者 put 方法把数据放入缓冲区,都会引起缓冲区的状态变化。
类似于流,但是可以异步读写数据(流只能同步读写),通道是双向的,(流是单向的),通道的数据总是要先读到一个 buffer 或者 从一个 buffer 写入,即通道与 buffer 进行数据交互。
FileChannel 比较特殊,它可以与通道进行数据交互, 不能切换到非阻塞模式,套接字通道可以切换到非阻塞模式;
nio 读取数据:任何时候读取数据,都不是直接从通道中读取,而是从通道读取到缓冲区,所以使用 NIO 读取数据可以分为下面三个步骤:
相当于一个观察者,用来监听通道感兴趣的事件,一个选择器可以绑定多个通道;使用 Selector 的好处在于: 使用更少的线程来就可以来处理通道了, 相比使用多个线程,避免了线程上下文切换带来的开销。有了 selector,可以用一个线程处理所有的 channel。通道向选择器注册时,需要指定感兴趣的事件,选择器支持以下事件:
如果你对不止一种事件感兴趣,那么可以用“位或”操作符将常量连接起来,如下:
int interestSet = SelectionKey.OP_READ| SelectionKey.OP_WRITE;
用“位与”操作 interest 集合和给定的 SelectionKey 常量,可以确定某个确定的事件是否在 interest 集合中。
通道向选择器注册时,会返回一个 SelectionKey 对象,具有如下属性:
Selector selector=Selector.open();
注册channel到selector上
Channel.configureBlocking(false)
SelectionKey key=channel.register(selector,SelectionKey.OP_READ)
注册到 server 上的 channel 必须设置成异步模式,否则异步 io 无法工作,这就意味着我们不可以把一个 Filechannel 注册到 selector,因为 filechannel 没有异步模式,但是 socketchannel 有异步模式