NIO概述

NIO是同步非阻塞IO,NIO的存在目的是为了让Java程序员可以实现高速I/O而无需编写自定义的本机代码,NIO将最耗时的I/O操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度.对于网络通信而言,NIO,AIO并没有改变网络通信的基本步骤,只是在其原来的基础上(socker ServiceSocket)做了一个改进.

Socket 和ServerSocket 建立的连接需要三次握手,对于三次握手建立稳定的连接性能开销比较大,解决的方式其实很简单,就是减少连接的次数,对我们的读写通信管道进行一个抽象,

对于读和写采用抽象的管道的概念:
Channel: Channe是在一个TCP连接之间的抽象,一个TCP连接可以对应多个管道而是以前的方式只有一个通信信道,这样就减少了TCP连接的次数,.

UDP采用了相同的方式,也是抽象成管道的概念,

ServiceSocketChannel.open() ; 相当于以前的 new ServerSocket();

为什么是同步非阻塞的


我们知道java nio是基于io多路复用模型,也就是我们经常提到的select,poll,epoll。io 多路复用本质是同步io,其需要调用方在读写事件就绪时主动去进行读写。在java nio中,通过selector来获取就绪的事件,当selector上监听的channel中没有就绪的读写时间时,其可以直接返回,或者设置一段超时后返回。可以看出java nio可以实现非则塞,而不像传统io里必须则塞当前线程直到可读或可写。所以,java nio可以实现非阻塞。

说白了就是通过selector(选择器)就相当管家,管理了所有的IO事件

IO事件:
客户端的connection ,服务端的accept , 客户端和服务端的读写,这些IO事件都交给selector管理

selector选择器如何进行管理IO事件?
当IO事件注册给我们的选择器的时候,选择器会给它们分配一个key值(可以简单的理解成一个事件的标签),当我们的IO事件完成后会通过key值来找到相应的管道,然后通过管道发送数据和接受数据等操作,这就是我们的selector.

对于读数据和写数据的缓冲区
数据缓冲区通常是通过bytebuffer这个类来实现,提供了很多读写的方法,比如说pu()t放入值,get()获取值,


管道
服务器:
ServerSocketChannel
客户端
SocketChannel

选择器:
Selector selector =Select.open(); //这样就打开了我们的选择器

selectionkey
可以通过它来判断IO事件是否已经就绪(比如说是否有数据可以读,缓冲区是否是空的,是否可以连接到客户端,服务端是否需要接收客户端的连接)

key.isAccptable:是否可以接收客户端的连接
key.isconnectionable:是否可以连接服务端
key.isreadable():缓冲区是否可读
key.iswriteable():缓冲区是否可写

如何获得事件的key
通过selector对象的selectedKeys() 可以获取selectionKey

如何注册到我们的选择器
selector.regist(Selector,Selectionkey.OP_Write);
selector.regist(Selector,Selectionkey.OP_Read);
selector.regist(Selector,Selectionkey.OP_Connet);
selector.regist(Selector,Selectionkey.OP_Accept);

Selector详解

https://www.cnblogs.com/snailclimb/p/9086334.html