非阻塞SOCKET
非阻塞的通信
ACCEPT:立即返回。如果没有client连接则返回null,有连接则返回SocketChannel(相当于阻塞网络通信里的Socket)
READ:立即返回
read()
:如果读不了则立即返回read(ByteBuffer)
:尽量读,可能读几个甚至0个字节,也可能返回-1表示连接关闭
WRITE:立即返回 可能写入几个甚至0个字节
哪些是非阻塞
NIO之前的IO都是阻塞的,NIO里面也有阻塞、非阻塞之分
阻塞NIO是继承于AbstractInterruptibleChannel,例如FileChannel
非阻塞的NIO是继承于SelectableChannel,包括ServerSocketChannel, SocketChannel(TCP), DatagramChannel(UDP)
SelectableChannel
SelectableChannel通过configureBlocking(boolean) 来设置阻塞/非阻塞
非阻塞实现:SelectableChannel + Selector
Selector
非阻塞的IO实现了不用阻塞,但仍需人工不断去询问,因此需要一个用来轮询的东西帮忙管理,这就是Selecter,类似于OS层面的select/epoll
- 存放的是SelectionKey
- 构造:Select.open()
Selector类似一个观察者,只要我们把需要探知的套接字通道socketchannel注册到Selector,程序不用阻塞等待,可以并行做别的事情,当有事件发生时,Selector会通知程序,传回一组SelectionKey,程序读取这些Key,就会获得注册过的socketchannel,然后,从这个Channel中读取和处理数据
- Selector内部原理实际是在做一个对所注册的channel的轮询访问,不断的轮询(目前就这一个算法),一旦轮询到一个channel有所注册的事情发生,比如数据来了,他就会站起来报告,交出一把钥匙,让我们通过这把钥匙来读取这个channel的内容。
SelectionKey
用于标注注册事件的信息,以Channel为单位,因为register()是Channel的方法
Channel
- Channel会发生事件:ACCEPT、READ、WRITE等
- Channel通过register()方法在Selector上注册需要监控的事件
-
- 其中Object是Attach的一个对象,取出时用 Selectionkey.attachment(),并强制类型转换