1. 程式人生 > >Java NIO 之 Selector

Java NIO 之 Selector

turn return bstr 函數 style tac alt ble ole

  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