JAVA NIO Selector 知識三
阿新 • • 發佈:2017-08-17
java nio
Selector(選擇器)
Selector工作流程:我們把想要的soketchannel告訴selector後,我們就去可以做別的事情,當有事件發生的時候,selector會通知我們,然後獲取selectionkey,獲得我們感興趣的事件。
selecotr是java nio多路復用的關鍵類,selector實現了一個線程管理多個channel,只需要更少的資源來處理更多的通道,節省線程之間的開銷,這麽說seletor是以前cpu很貴的時候,現在很多公司的機器都是多核,充分利用cpu才是最好的應用,後期會寫些JAVA NIO的最佳實踐netty。
下面寫幾個簡單的例子:
Seletor的創建方式:
Selector selector = Selector.open();
channel註冊到seletor上:
SelectionKey key = channel.register(selector,Selectionkey.OP_READ);
channel註冊到Selector後會返回一個SelectionKey對象,SelectionKey代表著這個channel和註冊的
selector的關系,SelectionKey維護著兩個重要的屬性interestOps和readyops。
Selector通常會監聽四種類型的事件:
connect
accept
read
write
這四種事件通常用Selectionkey對應的一些:
SelectionKey.OP_CONNECT
SelectionKey.OP_ACCEPT
SELECTIONKEY.OP_READ
SELECTIONKEY.OP_WRITE
//打開服務器端的套接字通道 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); //服務器端設置為非阻塞 serverSocketChannel.configureBlocking(false); //服務端進行綁定 serverSocketChannel.bind(new InetSocketAddress("localhost", 8000)); //註冊感興趣的事件 Selector selector = Selector.open(); SelectionKey selectionKey = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); selectionKey.* 可以查看一些感興趣的事件
select()方法:
int selectCount = selector.select();阻塞到至少有一個再註冊的通道上就緒了 selector.select(timeout);這個有超時時間 selector.selectNow();這個是到無論有沒有都立馬就返回了
selectedKeys()方法:
Set<SelectionKey> keys = selector.selectedKeys(); //獲取叠代器 Iterator<SelectionKey> keyIterator = keys.iterator();
獲取我我們需要的監聽的事件;
while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (!key.isValid()) { continue; } if (key.isAcceptable()) { ServerSocketChannel sscTemp = (ServerSocketChannel) key.channel(); //得到一個連接好的SocketChannel,並把它註冊到Selector上,興趣操作為READ SocketChannel socketChannel = sscTemp.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); System.out.println("REGISTER CHANNEL , CHANNEL NUMBER IS:" + selector.keys().size()); } else if (key.isReadable()) { //讀取通道中的數據 SocketChannel channel = (SocketChannel) key.channel(); read(channel); } keyIterator.remove(); //該事件已經處理,可以丟棄 }
JAVA NIO Selector 知識三