Selector

前面两个章节都描述了Buffer和Channel,那这个章节就描述NIO三个最核心部分的最后一块内容 - 选择器(Selector)
  

如何使用

  在前面的章节中描述过多路复用,一个线程通过选择器处理和管理多个通道。由此可见,选择器是用来处理多个通道并监听其通道事件的组件。

  • Create
      只需要调用 open() 即可创建一个Selector对象:

    Selector selector = Selector.open();
  • Register
      通过 register() 方法注册通道:

    ServerSocketChannel channel = ServerSocketChannel.open();
    channel.configureBlocking(false);
    SelectionKey selectionKey = channel.register(selector, SelectionKey.OP_ACCEPT);

      在注册通道之前,把通道设置成非阻塞模式,观察源码会发现 register() 会校验当前通道是否为非阻塞模式,当是阻塞模式时,会抛出IllegalBlockingModeException 异常。在前面一个章节也提过,为什么FileChannel没有继承SelectableChannel,因为它不需要多路复用,所以在使用通道的时候,只有FileChannel不能向选择器注册通道,凡是继承SelectableChannel都能够向选择器注册通道。
      注册通道方法的第二个参数是SelectionKey中定义的操作类型,你可以填入任何你感兴趣的操作类型,只要这个通道支持,同样,在执行 register() 方法时也会校验该通道是否能够支持该操作。
      注册方法同样也会返回一个SelectionKey对象。

  • Attach Object
      注册通道的 register() 方法有一个重载方法,可以向选择器注册通道的时候,选择想要带上的附加对象:

    public abstract SelectionKey register(Selector sel, int ops, Object att)
        throws ClosedChannelException;

    网友评论