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程式設計例項)。