NIO简介
NIO是Java对IO的替代,是一种同步非阻塞IO,面向缓冲区而不是流,所以效率更高。
早期NIO不够好,JDK7.0以后NIO大幅改善,称为NIO.2。提供Path类替代原来的File类,拥有更多方法,而且File类如果输入错误,返回false或null,而不是抛异常,Path类就解决了这个问题。还提高Paths、Files两个工具类。
组成
- Channel:类似于流,一个流可以和文件或网络Socket对应。如果向Channel写入数据就等于向文件或Socket写入。
- Buffer:是一个缓冲区,可以就理解为byte数组。数据要封装成Buffer的形式才能和Channel交互。
- Selector:抽象类SelectableChannel是接口Channel的一个实现,可以注册到Selector里,一个Selector对应一个线程,这样就可以可以用一个线程管理多个Channel
与IO的区别
NIO | IO |
---|---|
非阻塞 | 阻塞 |
面向缓存 | 面向流 |
通道可用 | 通道不可用 |
选择器可用 | 选择器不可用 |
Channel
SocketChannel
- SocketChannel继承了SelectableChannel,一个SocketChanne对应一个客户端。
- 可以通过attach方法绑定Java对象
clientKey.attach(echoClient);
ServerSocketChannel
- 根据端口监听客户端传来的请求
- 需要绑定端口号
ssc.socket().bind(isa);
Selector
创建
Selector selector = SelectorProvider.provider().openSelector();
向Selector注册通道
- 使用时要把channel注册到Selector里。
- 注册前要把channel设为非阻塞状态。
clientChannel.configureBlocking(false);
- 注册的方法是channel的register方法,有两个参数,分别是Selctor对象和“interest集合”
- “interest集合”表示的是通过Selector监听Channel时对什么事件感兴趣。
- 事件:Connect,Accept,Read,Write。
- ready集合,一旦事件被触发后完成,那么事件“就绪”,加入read集合。
SelectonKey
- 注册完后就会得到一个SelectonKey对象。
ServerSocketChannel ssc = ServerSocketChannel.open();
SelectionKey acceptKey = ssc.register(selector, SelectionKey.OP_ACCEPT);
- SelectonKey反映了一个channel和selector的对应关系。可以利用SelectonKey获取selector管理的channel或channel绑定的对象。
ServerSocketChannel server = (ServerSocketChannel) acceptKey.channel();
EchoClient echoClient = (EchoClient) acceptKey.attachment();
- SelectonKey有四个枚举属性分别表示四个事件:
SelectionKey.OP_CONNECT;
SelectionKey.OP_ACCEPT;
SelectionKey.OP_READ;
SelectionKey.OP_WRITE;
- SelectonKey有四个枚举属性分别表示四个事件的就绪状态:
selectionKey.isAcceptable();
selectionKey.isConnectable();
selectionKey.isReadable();
selectionKey.isWritable();
其他操作
- select():没有任务的时候挂起线程。
- wakeup():唤醒线程,即使被select方法挂起的线程也会被唤醒。
- close():关闭Selector。