NIO(non-block),是对`java.io.*`包的很多类进行改写,以<mark>块</mark>的方式处理数据,可以提供非阻塞的高伸缩性的网络通信。NIO相关API都在`java.nio.*`包下。
<br/>
NIO有三大核心部分组成:Channel,Buffer,Selector。
<br/>
BIO是基于字符流和字节流进行传输,而NIO则是基于Channel和Buffer传输。
<br/>
IO分为文件IO和网络IO。
<br/>
NIO是基于事件驱动,适合服务器需要维持大量的连接,但数据交换量不大的场合。
<br/>
**1. `java.nio.Buffer`**
![](https://img.kancloud.cn/ec/60/ec609757884bec8a83bce181891c96c1_1385x228.jpg)
Buffer是一个抽象父类,常用的子类有ByteBuffer、CharBuffer、IntBuffer、DoubleBuffer等,Java的每一种基本数据类型都有一个对应的Buffer。
<br/>
常用的是ByteBuffer,它的核心方法如下:
```java
put // 存储字节数据到缓冲区
get // 从缓冲区获取数据
array // 将缓存区数据转换为数组
allocate // 设置缓冲区的初始容量
wrap // 将现成的byte数组放入缓冲区
flip // 翻转缓冲区
```
**2. `java.nio.channels.Channel`**
![](https://img.kancloud.cn/e8/e4/e8e4cb92165da77e5ad4d21708b1dc29_1244x216.jpg)
Channel是一个接口,常用的实现类如下:
```
FileChannel 文件读写;
DatagramChannel UDP数据读写;
ServerSocketChannel、SocketChannel TCP数据读写;
```
```
FileChannel常用方法:
read // 从通道中读取数据放入缓冲区中
write // 缓冲区数据写入到通道中
transferFrom // 把目标通道的数据复制到当前通道
transferTo // 把当前通道的数据复制到目标通道中
ServerSocketChannel常用方法:
open // 返回一个新的ServerSocketChannel对象
bind // 绑定一个端口号
configureBlocking // 设置阻塞模式
accept // 接受一个连接
register // 注册一个Selector
SocketChannel常用方法:
open // 获取一个新的SocketChannel对象
configureBlocking // 设置阻塞模式
connect // 连接服务器
finishConnect // 连接不上服务器的处理
write // 往通道写数据
read // 从通道读数据
register // 注册一个Selector
```
**3. `java.nio.channels.Selector`**
![](https://img.kancloud.cn/b1/36/b13620f12dc6047ea7a8dcbfc1254eb9_1143x169.jpg)
Selector选择器,能够检测多个注册的通道是否有事件发生。如果有事件发生,获取该事件然后针对该事件进行相应的处理,这样可以只用一个线程去管理多个通道(多个连接),极大地减少了系统开销,简化了初始化成本和多线程之间上下文切换的成本。
<br/>
Selector常用方法:
```
open // 获取一个Selector对象
select // 监控到IO操作进行时,将对应的selectionKey加入到内部集合并返回
selectedKeys // 返回此选择器的选择键集
SelectionKey表示选择器与通道的注册关系,它有如下属性:
static int OP_ACCEPT // 有新的网络连接可以accept(接收),值为16
static int OP_CONNECT // 连接已经建立,值为8
static int OP_READ // 读操作,值为1
static int OP_WRITE // 写操作,值为4
selector // 获取与之关联的Selector
channel // 获取与之关联的Channel
attachment // 获取与之关联的共享数据
interestOps // 设置或改变监听事件
```
- 网络通信
- 网络协议
- 端口和套接字
- TCP网络程序
- UDP网络程序
- 多线程聊天室
- 多线程
- 线程相关概念
- 线程实现方式
- 中断线程
- 线程生命周期
- 线程优先级
- 优先级规则
- 案例演示
- 线程同步机制
- 线程同步机制
- synchronized关键字
- ReentrantLock类
- Condition类
- 监视器概念
- volatile关键字
- final变量
- 死锁
- 线程局部变量
- 读/写锁
- 原子类
- 阻塞队列
- 工作规则
- 案例演示
- 常用阻塞队列
- 线程安全集合
- 高效的映射/集/队列
- 并发集视图
- 写数组的拷贝
- Arrays类的并行数组算法
- 同步包装器
- Callable与Future
- 执行器
- 线程池
- 预定执行
- 控制任务组
- Fork-Join框架
- 同步器
- 同步器
- 信号量
- CountDownLatch类
- CyclicBarrier类
- Exchanger类
- SynchronousQueue类
- 线程与Swing
- Swing与线程问题
- 两个原则
- Swing工作线程
- 单一线程规则
- 文件IO
- File类
- 文件输入输出
- ZIP压缩文件
- 集合
- 集合框架
- 集合接口
- 集合实现类
- 线程安全集合
- 集合算法
- 迭代器
- 集合排序
- JDBC
- JDBC是什么
- JDBC-ODBC桥
- JDBC驱动程序类型
- JDBC常用类与接口
- 数据库操作
- 连接数据库
- 增/删/改/查/预处理
- 事务
- 批处理
- commons-dbutils工具
- 安全问题
- Jedis
- 使用Jedis操作Redis数据库
- JSON转换
- 使用连接池
- 案例
- 单例破坏
- 单例定义
- 单例实现方式
- 懒汉式实现单例
- 饿汉式实现单例
- 单例破坏
- 类的单例破坏
- 枚举的单例破坏
- 克隆
- 克隆是什么
- 浅克隆
- 深克隆
- 注解
- 注解是什么
- 三大注解
- 内置注解
- 元注解
- 自定义注解
- NIO
- 相关概念
- BIO/NIO/AIO
- 多线程编程
- 线程同步
- 线程通信
- NIO
- NIO三大核心组件
- NIO网络编程
- NIO文件读写
- AIO
- Java8新特性
- Lambda表达式
- 方法引用
- 函数式接口
- 默认方法
- 什么是默认方法
- 默认方法语法格式
- 多个同名的默认方法问题
- 静态默认方法
- 默认方法实例
- Stream
- Stream是什么
- Stream示例
- Optional容器
- 新的日期时间API
- Base64
- SPI
- SPI是什么
- SPI与API的区别
- 常见场景
- 使用SPI需遵循的约定
- SPI使用步骤