参考自

Java NIO系列教程(六) Selector

Java-NIO-Selector

java.nio.channels.Selector

NIO新功能Top 10(下)

出发点: 如何管理多个连接?
  1. 所有连接注册到一个管理组件,当它们的状态改变(比如有数据可读、可写),就向这个管理组件发出信息。即,这个管理组件被动地监听
  2. 一个管理组件主动地一直轮询所有组件。
第一种模式很像操作系统的“中断”这种模型,可以在操作系统层面上实现。即这个管理组件可以在无事件时进入阻塞状态,当连接状态改变,它被唤醒,这时,主动方在产生事件的地方,这是一种高效的方式。
第二种模式,主动方在管理组件,由于它事先不知道连接的状态,因此这种轮询的效率很低。更会无意义地消耗CPU和IO资源。
 
读选择器建立在非阻塞模式上,所以只有通道是非阻塞模式它才会工作。如果你喜欢,还可以让实际的选择处理也变成非阻塞的。重点是Selector对象会帮助你卖力地检查大量通道的状态,你只需要操作选择的结果而不用亲自去管理每一个通道。
 
 
Selector 的出现,大大改善了多个 Java Socket的效率。在没有NIO的时候,轮询多个socket是通过read阻塞来完成,即使是非阻塞模式,我们在轮询socket是否就绪的时候依然需要使用系统调用。而Selector的出现,把就绪选择交给了操作系统(我们熟知的selec函数),把就绪判断和读取数据分开,不仅性能上大有改善,而且使得代码上更加清晰。 
 
 

Java NIO的选择器部分,实际上有三个重要的类。 

1,Selector 选择器,完成主要的选择功能。select(), 并保存有注册到他上面的通道集合。  如何通过selector获得所有注册的通channel? 
2,SelectableChannel 可被注册到Selector上的通道。  包括啥,不包括啥?
3,SelectionKey 描述一个Selector和SelectableChannel的关系。并保存有通道所关心的操作。 怎么通过SelectionKey获得通道所关心的操作? 什么叫做“通道所关心的操作”?

 
 
答案:
 
1,Selector 选择器,完成主要的选择功能。select(), 并保存有注册到它上面的通道集合。  如何通过selector获得所有注册的通channel?  => Selector的keys()方法获取SelectionKey的集合,再通过SelectionKey的channel()方法获得channel
2,SelectableChannel 可被注册到Selector上的通道。  包括啥,不包括啥? 包括DatagramChannelPipe.SinkChannelPipe.SourceChannel,ServerSocketChannelSocketChannel 。不包括FileChannel
3,SelectionKey 描述一个Selector和SelectableChannel的关系。并保存有通道所关心的操作。 怎么通过SelectionKey获得通道所关心的操作? 什么叫做“通道所关心的操作”? SelectionKey的interestOps()返回interest set,这是一个int值。
 什么叫做“通道所关心的操作”?
  • The interest set determines which operation categories will be tested for readiness the next time one of the selector's selection methods is invoked. The interest set is initialized with the value given when the key is created; it may later be changed via the interestOps(int) method.

  • 即,这个channel会被检测发生了什么事件。比如成功建立连接,可以接受新连接,可读,可写
  • SelectionKey.OP_CONNECT 当一个socket channel成功连接到另一个服务器时,称为“连接就续”, 通过isConnectable()判断。
  • SelectionKey.OP_ACCEPT 当一个server socket channel准备好接收新进入的连接,称为“连接就绪”。isAcceptable()
  • SelectionKey.OP_READ 当一个channel有数据可读时,称为“读就绪”. isReadable()
  • SelectionKey.OP_WRITE 当一个channel等待被写入时,称为"写就绪". isWritable()
 

即interest set用来在select过程中用来测试一个channel己经准备好了进行哪些操作。

 
获取selectedKeys
 
使用selector.selectedKeys()
public abstract Set<SelectionKey> selectedKeys()
Keys may be removed from, but not directly added to, the selected-key set. Any attempt to add an object to the key set will cause an UnsupportedOperationException to be thrown.
只可从中移除key,但不可以增加key。
 
在使用selector时,获取完key,并进行完操作后,需要把它从selectedKeys集合中删除。
 
SelectionKey类
 
A token representing the registration of a SelectableChannel with a Selector.
 

select方法

select()方法返回的int值表示有多少通道已经就绪。亦即,自上次调用select()方法后有多少通道变成就绪状态。
注意,是”之间“有多少通道就绪。所以可能不等于就绪的通道总数。
 但是select方法返回的集合却不只包含了两次select之间发生变化的channel,而包含了所有“准备好”的channel。这里的“准备好”是指对于那个channel注册的interest集合里的操作“准备好”。
下面是JDK里对于selection的说明

Selection

During each selection operation, keys may be added to and removed from a selector's selected-key set and may be removed from its key and cancelled-key sets. Selection is performed by the select(),select(long), and selectNow() methods, and involves three steps:

  1. Each key in the cancelled-key set is removed from each key set of which it is a member, and its channel is deregistered. This step leaves the cancelled-key set empty.

  2. The underlying operating system is queried for an update as to the readiness of each remaining channel to perform any of the operations identified by its key's interest set as of the moment that the selection operation began. For a channel that is ready for at least one such operation, one of the following two actions is performed:

    1. If the channel's key is not already in the selected-key set then it is added to that set and its ready-operation set is modified to identify exactly those operations for which the channel is now reported to be ready. Any readiness information previously recorded in the ready set is discarded.

    2. Otherwise the channel's key is already in the selected-key set, so its ready-operation set is modified to identify any new operations for which the channel is reported to be ready. Any readiness information previously recorded in the ready set is preserved; in other words, the ready set returned by the underlying system is bitwise-disjoined into the key's current ready set.

  3. If all of the keys in the key set at the start of this step have empty interest sets then neither the selected-key set nor any of the keys' ready-operation sets will be updated.

  4. If any keys were added to the cancelled-key set while step (2) was in progress then they are processed as in step (1).

Whether or not a selection operation blocks to wait for one or more channels to become ready, and if so for how long, is the only essential difference between the three selection methods.

 

close()

用完Selector后调用其close()方法会关闭该Selector,且使注册到该Selector上的所有SelectionKey实例无效。通道本身并不会关闭。

 
 
 
 

NIO的Selector的更多相关文章

  1. Java NIO类库Selector机制解析(下)

    五.  迷惑不解 : 为什么要自己消耗资源? 令人不解的是为什么我们的Java的New I/O要设计成这个样子?如果说老的I/O不能多路复用,如下图所示,要开N多的线程去挨个侦听每一个Channel ...

  2. Java NIO类库Selector机制解析(上)

    一.  前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...

  3. Java NIO 选择器(Selector)的内部实现(poll epoll)

    http://blog.csdn.net/hsuxu/article/details/9876983 之前强调这么多关于linux内核的poll及epoll,无非是想让大家先有个认识: Java NI ...

  4. NIO组件Selector调用实例

    *对于nio的非阻塞I/O操作,使用Selector获取哪些I/O准备就绪,注册的SelectionKey集合记录关联的Channel这些信息.SelectionKey记录Channel对buffer ...

  5. NIO组件Selector工作机制详解(上)

    转自:http://blog.csdn.net/haoel/article/details/2224055 一.  前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但 ...

  6. Java NIO类库Selector机制解析--转

    一.  前言 自从J2SE 1.4版本以来,JDK发布了全新的I/O类库,简称NIO,其不但引入了全新的高效的I/O机制,同时,也引入了多路复用的异步模式.NIO的包中主要包含了这样几种抽象数据类型: ...

  7. Java NIO之Selector(选择器)

    历史回顾: Java NIO 概览 Java NIO 之 Buffer(缓冲区) Java NIO 之 Channel(通道) 其他高赞文章: 面试中关于Redis的问题看这篇就够了 一文轻松搞懂re ...

  8. Nio使用Selector客户端与服务器的通信

    使用NIO的一个最大优势就是客户端于服务器自己的不再是阻塞式的,也就意味着服务器无需通过为每个客户端的链接而开启一个线程.而是通过一个叫Selector的轮循器来不断的检测那个Channel有消息处理 ...

  9. Java NIO 选择器(Selector)的内部实现(poll epoll)(转)

    转自:http://blog.csdn.net/hsuxu/article/details/9876983 之前强调这么多关于linux内核的poll及epoll,无非是想让大家先有个认识: Java ...

随机推荐

  1. Animated App Boot Example : Fastest animation at app boot time

    This iPhone app shows how to create an animation that is displayed when the app starts. The animatio ...

  2. private继承

    private继承并不如public继承一样具有is-a的关系. ------------------------------------------------------------------- ...

  3. STL Traits编程技法

    traits编程技法大量运用于STL实现中.通过它在一定程度上弥补了C++不是强型别语言的遗憾,增强了C++关于型别认证方面的能力. traits编程技法是利用“内嵌型别”的编程技法和编译器的temp ...

  4. CSS的引入方式

    再用HTML编写的文本中,有是没能达到我们想要的效果,此时此刻我们可以用过引用CSS来控制!这不仅使得效果好而且代码层次清晰.CSS的引入方式可以分为四类: 1.链入外部样式表,就是把样式表保存为一个 ...

  5. response返回随笔

    response.setHeader("Content-type", "text/html;charset=UTF-8");//这句话的意思,是让浏览器用utf ...

  6. 网站如何做到完全不需要jQuery

    jQuery是现在最流行的JavaScript工具库. 据统计,目前全世界57.3%的网站使用它.也就是说,10个网站里面,有6个使用jQuery.如果只考察使用工具库的网站,这个比例就会上升到惊人的 ...

  7. Python Generators vs Iterators

    http://stackoverflow.com/questions/2776829/difference-between-python-generators-vs-iterators iterato ...

  8. 設定 Bootstrap/SASS/Bower/gulp (Windows平台)

    請注意:在進行以下步驟前,你會需要先安裝git,可以參考這篇 git安裝教學 前言 時至今日,幾乎每個人都在討論bootstrap.less 或 sass.我們知道它們是比較新的前端技術,而且有開始愈 ...

  9. C#网络通信

    Server: using System.Net; using System.Net.Sockets; using System; using System.Collections.Generic; ...

  10. IP HELPER GetAdaptersAddresses 函数

    自己做的一些笔记,XP以及以后的系统使用: MSDN 函数:http://msdn.microsoft.com/en-US/library/windows/desktop/aa365915(v=vs. ...