NIO网络编程之Selector介绍

Selector

要实现异步IO要通过Selector,甚至我们可以通过一个线程管理多个Channel的读写,这是NIO相较BIO的优越之处之一。

Channel可以注册到一个Selector上,Selector可以监视多个Channel的状态

Channel的状态有四种:

  • CONNECT
  • ACCEPT
  • READ
  • WRITE

CONNECT代表某个Channel成功连接到另一个服务器(客户端)。ACCEPT则是一个ServerSocketChannel准备好接收新连接(服务端)。READ代表该Channel有数据可读,WRITE代表该Channel等待写操作。

这些状态在Java中对应SelectionKey中的四个常量

  • SelectionKey.OP_CONNECT
  • SelectionKey.OP_ACCEPT
  • SelectionKey.OP_READ
  • SelectionKey.OP_WRITE

在给Channel注册到Selector时可以指定要监听的状态:

channel.configureBlocking(false);
SelectionKey key =channel.register(selector,SelectionKey.OP_READ);

这个状态可以是多个状态合成的,我们叫它interestOps,是任意几个状态的位或结果。

register方法可以返回一个SelectionKey,作为注册在该Selector上的Channel的唯一标识(一个Selector-Channel对)。

Selector的常用API:

  • int select():阻塞等待,直到至少有一个绑定的Channel符合监听的状态,返回符合状态Channel的个数,也可能是0(如果中途有一个Key的interestOps被更新了)。
  • int select(long timeout) :阻塞等待限制一个最长时间,超过时间直接返回。
  • int selectNow():不阻塞,直接查询有几个符合监听状态的Channel。
  • Set<SelectionKey> selectedKeys():经过任一select操作后可以获取被select到的keys。
  • Selector wakeup():如果一个线程调用select()方法阻塞了,可以让另一个线程调用同一个Selector上的wakeup()方法来唤醒这个线程。
  • void close():关闭这个Selector。

SelectionKey

SelectionKey的常用API:

  • int interestOps():返回interestOps,可以通过与常量进行位与来判断是否含有某个状态。
  • int readyOps():返回的是有哪些监听的状态目前是对应的,也是合成值,可以通过与常量进行位与来判断是否含有某个状态。或者直接调用isConnectable,isAcceptable,isReadable,isWritable
  • SelectableChannel channel():获取这个SelectionKey对应的Channel
  • Selector selector(): 获取这个SelectionKey对应的Selector
  • Object attach(Object ob):给这个SelectionKey附加一个Object对象
  • Object attachment():获取这个附加的Object对象

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/nio%e7%bd%91%e7%bb%9c%e7%bc%96%e7%a8%8b%e4%b9%8bselector%e4%bb%8b%e7%bb%8d/

发表评论

电子邮件地址不会被公开。