首页   快速返回

java NIO selector     所属分类 netty 浏览量 38
A multiplexor of SelectableChannel objects.


Selector 多路复用 SelectableChannel对象, 识别通道是否发生感兴趣的事件 譬如读写事件 


// 1.创建Selector
Selector selector = Selector.open();

// 2.将Channel注册到选择器中

//  注册到Selector上的 Channel 必须是非阻塞的,FileChannel 是阻塞的,不可以注册到Selector 
channel.configureBlocking(false);

// 第二个参数指定 感兴趣事件
// 可使用或运算| 组合多个事件  SelectionKey.OP_READ | SelectionKey.OP_WRITE 
SelectionKey key = channel.register(selector , SelectionKey.OP_READ);

// 一个 Channel 仅仅可以被注册到一个 Selector 一次, 如果将 Channel 注册到 Selector 多次, 相当于更新 SelectionKey 的 interest set.


SelectionKey 类型

OP_READ 可读事件 1<<0   1 
OP_WRITE 可写事件 1<<2  4
OP_CONNECT 客户端连接服务端的事件(tcp连接)  1<<3  8
OP_ACCEPT 服务端接收客户端连接的事件 1<<4  16


一个Selector内部维护了三组keys

key set:当前channel注册在Selector上所有的key 可调用keys()获取
selected-key set:当前channel就绪的事件 可调用selectedKeys()获取
cancelled-key:主动触发SelectionKey#cancel()方法会放在该集合,前提条件是该channel没有被取消注册 不可通过外部方法调用


Selector类方法 

open():创建一个Selector对象
isOpen():是否是open状态,如果调用了close()方法则返回false
provider():获取当前Selector的Provider

Selector的具体实现
openjdk SelectorImpl
linux2.6以后 EpollSelectorImpl
Windows平台 WindowsSelectorImpl
MacOSX平台 KQueueSelectorImpl

keys()  获取当前channel注册在Selector上所有的key
selectedKeys():获取当前channel就绪的事件列表
selectNow():获取当前是否有事件就绪,立即返回结果,不会阻塞;如果返回值>0,则代表存在一个或多个
select(long timeout): 带超时的阻塞方法 ,超时后直接返回
select():  阻塞方法,直到有事件就绪才会返回
wakeup():调用该方法,阻塞在select()上的线程立马返回   
close():  关闭Selector,使注册到该Selector上的所有SelectionKey实例无效。channel本身不会关闭。


往Channel注册Selector会返回一个SelectionKey对象 ,包含如下信息


interest set,当前Channel感兴趣的事件集 
ready set
channel
selector
attached object,可选的附加对象

// 返回当前感兴趣的事件列表
int interestSet = key.interestOps();

// 可通过interestSet判断其中包含的事件
boolean isInterestedInAccept  = interestSet & SelectionKey.OP_ACCEPT;
boolean isInterestedInConnect = interestSet & SelectionKey.OP_CONNECT;
boolean isInterestedInRead    = interestSet & SelectionKey.OP_READ;
boolean isInterestedInWrite   = interestSet & SelectionKey.OP_WRITE;    

// 可通过interestOps(int ops)方法修改事件列表
key.interestOps(interestSet | SelectionKey.OP_WRITE);
ready set
当前Channel就绪的事件列表

int readySet = key.readyOps();

key.isReadable();    //读事件是否就绪
key.isWritable();    //写事件是否就绪
key.isConnectable(); //客户端连接事件是否就绪
key.isAcceptable();  //服务端连接事件是否就绪

channel和selector
通过SelectionKey来获取当前的channel和selector

// 返回当前事件关联的通道, ServerSocketChannel SocketChannel 
Channel channel = key.channel();

// 返回当前事件所关联的Selector对象
Selector selector = key.selector();
attached object
可在selectionKey中附加一个对象

key.attach(theObject);
Object attachedObj = key.attachment();

在注册时直接附加
SelectionKey key = channel.register(selector, SelectionKey.OP_READ, theObject);

上一篇     下一篇
netty高性能之道

PooledByteBufAllocator跟踪调试

netty代码debug切入点

缓存雪崩穿透预热更新降级

服务器性能指标介绍

spring资源Resource接口