Java NIO 之 Selector

Posted luojiahu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java NIO 之 Selector相关的知识,希望对你有一定的参考价值。

  Selector是SelectableChannel的多路选择器,配合SelectableChannel实现非阻塞IO. 详见代码

/**
 * Selector 是 SelectableChannel的多路选择器</p>
 * SelectableChannel 通过register函数注册到Selector上</p>
 * 
 * Selector 维护三个key集合:</br>
 * 1. 指代当前注册到selector上的channel的key集合</br>
 *    执行register操作,将会把channel的key添加到集合中,key集合其本身不可直接修改</br>
 * 2. selected-key集合,其中的key指代的channel上至少有一个在上一次selection期间可执行的操作</br>
 *    执行select操作,将会把key添加到selected-key集合中.</br>
 * 3. cancelled-key集合,其中的key已经被撤销但所指代的channel未从selector注销</br>
 *    撤销的key所指代的channel在下一次select期间将会被注销.</br>
 * 上述三个集合在Selector创建之初均为空</p>
 * 
 * Selection操作分为三步</p>
 * 1. cancelled-key集合中的key将会被从所有key集合中删除,其通道将会被注销.这步执行结束后会导致cancelled-key集合为空</br>
 * 2. selection操作开始时,底层操作系统将会返回所有channel当前可执行的操作的key,对于任一符合条件的channel:
 * </t>1. 若key不是selected-key的元素,将被加入其中。其可执行的操作集合会被更新,并且通知channel,该集合中之前的所有记录会被丢弃。</br>
 * </t>2. 若是selected-key的元素,可执行操作将被添加到集合中,集合中之前的记录保留.</br>
 * 3. 若在第二步执行过程中key被加入cancelled-key中,则他们将会按照第一步所述操作处理</br>
 * 
 * @author luojiahu
 *
 */
public abstract class Selector implements Closeable {

	/**
	 * 返回key集合
	 * @return
	 */
	public abstract Set<SelectionKey> keys();
	
	/**
	 * 返回selected key集合
	 * @return
	 */
	public abstract Set<SelectionKey> selectedKeys();
	
	/**
	 * 阻塞selection timeout时间。不保证实时返回
	 * @param timeout
	 * @return
	 * @throws IOException
	 */
	public abstract int select(long timeout) throws IOException;
	
	/**
	 * 阻塞selection
	 * @return
	 * @throws IOException
	 */
	public abstract int select() throws IOException;
	
	/**
	 * 非阻塞selection。若从上次selection结束到这次开始没有channel变为selectable则返回0
	 * @return
	 * @throws IOException
	 */
	public abstract int selectNow() throws IOException;
}

  Selector 和 SelectableChannel间通过SelectionKey表示注册关系:

/**
 * 表示selectable channel在selector上的注册关系</p>
 * 
 * 维护两个operation set: 1. interest set 2. ready set</p>
 * 
 * 线程安全</p>
 * 
 * 支持attachment</p>
 * @author luojiahu
 *
 */
public abstract class SelectionKey {

	/**
	 * 返回对应的channel
	 * @return
	 */
	public abstract SelectableChannel channel();
	
	/**
	 * 返回对应的Selector
	 * @return
	 */
	public abstract Selector selector();
	
	/**
	 * 解除channel和register间的注册关系
	 */
	public abstract void cancel();
	
	/**
	 * 返回interest operation set
	 * @return
	 */
	public abstract int interestOps();
	
	/**
	 * 设置interest operation set
	 * @param ops
	 * @return
	 */
	public abstract SelectionKey interestOps(int ops);
	
	/**
	 * 返回 ready operation set
	 * @return
	 */
	public abstract int readyOps();
	
	/**
	 * 读,写,连接,接受连接
	 */
	public static final int OP_READ    = 1 << 0;
	public static final int OP_WRITE   = 1 << 2;
	public static final int OP_CONNECT = 1 << 3;
	public static final int OP_ACCEPT  = 1 << 4;
	
	/**
	 * 是否可读
	 * @return
	 */
	public final boolean isReadable() {
		return (readyOps() & OP_READ) != 0;
	}
}

  SelectorProvider

  SelectorProvider用于提供selector或者 selectable channel, 其本身持有一个SelectorProvider类型的对象。在一个JVM中SelectorProvider只有一个实例,通过本身的provider方法返回JVM唯一的SelectorProvider。

 

以上是关于Java NIO 之 Selector的主要内容,如果未能解决你的问题,请参考以下文章

Java NIO之Selector(选择器)

JAVA-5NIO之Selector

java nio之selector

Java NIO之Selector(选择器)

Java NIO之Selector(选择器)

Java NIO之Selector(选择器)