JavaSE:NIO - 选择键(SelectionKey) & Selector的使用流程

1.  选择键

    Channel 和 Selector的关系确定好后,并且一旦通道处于某种就绪状态,就可以被选择器查询到。

         那么,怎么进行查询呢?

      这个工作,使用选择器Selector的select() 方法完成。 

      select()方法:对感兴趣的通道操作,进行就绪状态的查询。

       

      Selector可以不断地查询Channel中发生的操作的状态。并且挑选感兴趣的操作的就绪状态。

      一旦通道有操作的就绪状态达成,并且是Selector感兴趣的操作,就会被Selector选中,放入选择键集合中。

 

    select():  选择器等待客户端连接的方法

            阻塞问题:

              1. 在开始没有客户访问的时候,是阻塞的

              2. 在有客户来访问的时候,方法会变成非阻塞的

              3. 如果客户的访问,被处理结束之后,又会恢复成阻塞的

 

    selectedKeys():   选择器会把被连接的服务器对象,放在Set集合中,这个方法就是返回一个Set集合

 

2.  Selector的使用流程

      <1> 创建Selector

          Selector对象,是通过调用静态工厂方法open(),来实例化的,如下:    

1     // 1. 获取Selector选择器
2     Selector selector = Selector.open();           

 

      <2>将Channel注册到Selector

          要实现Selector管理Channel,需要将channel注册到相应的Selector上:

 1 // 2. 获取通道
 2 
 3 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
 4 
 5 
 6 
 7 // 3. 设置为非阻塞
 8 
 9 serverSocketChannel.configureBlocking(false);
10 
11 
12 
13 // 4. 绑定连接
14 
15 serverSocketChannel.bind(new InetSocketAddress(SystemConfig.SOCKET_SERVER_PORT));
16 
17 
18 
19 // 5. 将通道注册到选择器上, 并制定监听事件为:"接收"事件
20 
21 serverSocketChannel.register(selector, Selection.OP_ACCEPT);

  上面通过调用通道的register()方法,会将它注册到一个选择器上

  首先需要注意的是:

  与Selector一起使用时,Channel必须处于非阻塞模式下,否则将抛出异常IllegalBlockingModeException

 

3. 轮询查询就绪操作

  万事俱备,下一步是查询就绪的操作

  通过Selector的select()方法,可以查询出已经就绪的通道操作,这些就绪的状态集合,包存在一个元素是SelectionKey对象的Set集合中。

  select()方法返回的int值,表示有多少通道已经就绪

       

 

 

  而一旦调用select()方法, 并且返回值不为0时,下一步该怎么做?

   

 

  通过调用Selector的selectedKeys()方法,来访问已选择键集合,然后迭代集合的每一个选择键元素,根据就绪操作的类型,

  完成对应的操作(见下篇:NIO编程实例)。

posted @ 2021-07-02 10:53  Jasper2003  阅读(312)  评论(0编辑  收藏  举报