Selector

Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。

创建

 Selector selector = Selector.open();

注册

// channel设置为非阻塞
channel.configureBlocking(false);    
//channel根据感兴趣的状态,注册到selector
SelectionKey key = channel.register(selector, Selectionkey.OP_READ | SelectionKey.OP_WRITE);    

就绪的channel

// 阻塞到至少有一个通道在你注册的事件上就绪了
int select();
// 和select()一样,除了最长会阻塞timeout毫秒
int select(long timeout);
// 不会阻塞,不管什么通道就绪都立刻返回
int selectNow();

SelectionKey

SelectionKey对象是用来跟踪注册事件的句柄。在SelectionKey对象的有效期间,Selector会一直监控与SelectionKey对象相关的事件,如果事件发生,就会把SelectionKey对象加入到selected-keys集合中。

SelectionKey.OP_CONNEC

连接就绪

SelectionKey.OP_ACCEPT

接收就绪

SelectionKey.OP_READ

读就绪

SelectionKey.OP_WRITE

写就绪

例子

Selector selector = Selector.open();
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
while(true) {
  int readyChannels = selector.select();
  if(readyChannels == 0) continue;
  Set selectedKeys = selector.selectedKeys();
  Iterator keyIterator = selectedKeys.iterator();
  while(keyIterator.hasNext()) {
    SelectionKey key = keyIterator.next();
    if(key.isAcceptable()) {
        // a connection was accepted by a ServerSocketChannel.
    } else if (key.isConnectable()) {
        // a connection was established with a remote server.
    } else if (key.isReadable()) {
        // a channel is ready for reading
    } else if (key.isWritable()) {
        // a channel is ready for writing
    }
    keyIterator.remove();
  }
}

Last updated