JAVA NIO 翻譯系列(六、Selector)

selector是一個檢測一個或者多個channel的組件深纲,能偵測哪個channel裝備好寫或者讀操作仲锄。這種方式下,一個單線程就可以管理多個channel或者多個網絡鏈接湃鹊。


為什么使用selector儒喊?

使用單線程去處理多channel的優(yōu)勢就是你只需要少量的線程去處理多channel。甚至涛舍,你可以用一個線程去處理所有的channel澄惊。對操作系統(tǒng)來說,線程切換是很費資源的富雅,并且在操作系統(tǒng)中掸驱,每個線程都會占據資源(內存),因此線程越少没佑,越好毕贼。

但請記住,現(xiàn)代的操作系統(tǒng)和cpu在多任務處理上正變的越來越好蛤奢,多線程花費的時間越來越少鬼癣。實際上陶贼,如果一個cpu是多核的,你不做多任務處理的話待秃,可能正是一種資源浪費拜秧。總之章郁,這塊屬于不同區(qū)域的討論枉氮。僅對此處而言,一個selector可以用一個縣城來處理多個Channel暖庄。


Java NIO: A Thread uses a Selector to handle 3 Channel's

Creating a Selector

創(chuàng)建一個selector:

Selector selector = Selector.open();


注冊channel到Selector上:


使用selector的前提就是channel必須是在非阻塞的模式下聊替。這就意味著你不能將FileChannel注冊到selector上,前面文章的例子都是FileChannel培廓。但是Socket 相關的channel就能很好的使用selector惹悄。

注意register方法的第二個參數(shù),

這是一個有趣的設置肩钠,意味著這個channel通過selector對什么事件感興趣泣港,有以下四個事件可以監(jiān)聽到:

? ? ?Connect ? ? Accept ? ? Read ? ?Write

一個Channel啟動一個事件代表它為這個事件轉備好了。因此蔬将,channel鏈接上服務器就是一個連接準備爷速,一個socket Channel接受一個連接代表接受事件,一個channel有數(shù)據準備去讀代表一個準備讀事件霞怀。

如果一個selector對多個事件感興趣,則

int interestSet = SelectionKey.OP_READ | SelectionKey.OP_WRITE;

傳入到register方法中莉给。


SelectionKey

register()方法的返回對象就是SelectionKey毙石。SelectionKey含有幾個有意思的特性;



Interest Set

通過以下方法可以獲得register()方法的時候的事件類型

你可以使用&連接符連接SelectionKey的常量來找出Selector對哪些事件感興趣

Ready Set

ready set 是channel的一些列可操作的狀態(tài)集合颓遏,你可以獲取這個狀態(tài)集合通過一個selection徐矩。

int readySet = selectionKey.readyOps();

下面的方法跟上面的效果一樣

selectionKey.isAcceptable();

selectionKey.isConnectable();

selectionKey.isReadable();

selectionKey.isWritable();


Channel + Selector

你可以通過SelectionKey來訪問Channel和Selector對象

Channel? channel? = selectionKey.channel();

Selector selector = selectionKey.selector();


Attaching Objects

你可以在selectionKey附加一個Object對象,來標識channel對象以便找出你要的channel對象叁幢,或者附加一些其他的信息滤灯。舉個栗子,你可以將buffer對象附加在上面

selectionKey.attach(theObject);

Object attachedObj = selectionKey.attachment();

你可以在注冊Selector的時候把對象附加上去

SelectionKey key = channel.register(selector, SelectionKey.OP_READ, theObject);


Selecting Channels via a Selector

一旦你注冊了一個或者多個channel到一個Selector上面曼玩,你就可以調用以下三個select方法鳞骤。這些方法會返回準備好的事件的對象,這些事件(connect,accept,read 或者write)都是你當初注冊Selector時候傳遞的黍判。換句話說如果你注冊的時候是傳遞的讀事件豫尽,那么當你調用select的時候,獲得當前準備去讀的channels顷帖。

int select()

int select(long timeout)

int selectNow()

select()會阻塞美旧,直到至少一個已經轉備好事件的channel渤滞。

select(long timeout)?跟上面方法一樣,除了他會在timeout毫秒內會阻塞.

selectNow()不會阻塞榴嗅,會立即返回


selectedKeys()

當你調用select()方法的時候妄呕,返回的值代表有多少個channel準備好了,你可以通過selected key set去訪問準備好的channel

Set selectedKeys = selector.selectedKeys();

When you register a channel with aSelectortheChannel.register()method returns aSelectionKeyobject. This key represents that channels registration with that selector. It is these keys you can access via theselectedKeySet()method. From theSelectionKey.

當你調用channel的register的方法的時候嗽测,會返回一個SelectionKey趴腋。這個代表channel和selector的關系

remove方法是必須要調用的,當你處理好channel论咏。通過SelectionKey.channel()會獲得channel對象优炬,你可以類型轉換你要的Channel對象,比如ServerSocketChannel等


wakeUp()

一個線程調用select()就會阻塞厅贪,但是也可以脫離select()方法回到非阻塞狀態(tài)蠢护,即使沒有channel轉備好。這種方式就是讓其他線程調用那個selector的wakeup()方法养涮,然后select()方法會立即返回葵硕。

如果另外一個線程調用這個selector的wakeup方法,并且原來調用selector的select()方法的線程并沒有阻塞贯吓,那么下一個調用selector的select()方法會立即返回懈凹。

close()

與注冊相反,這個方法會使所有的selectKey無效

完整的栗子


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末悄谐,一起剝皮案震驚了整個濱河市介评,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌爬舰,老刑警劉巖们陆,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異情屹,居然都是意外死亡坪仇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門垃你,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椅文,“玉大人,你說我怎么就攤上這事惜颇〗源蹋” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵官还,是天一觀的道長芹橡。 經常有香客問我,道長望伦,這世上最難降的妖魔是什么林说? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任煎殷,我火速辦了婚禮,結果婚禮上腿箩,老公的妹妹穿的比我還像新娘豪直。我一直安慰自己,他們只是感情好珠移,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布弓乙。 她就那樣靜靜地躺著,像睡著了一般钧惧。 火紅的嫁衣襯著肌膚如雪暇韧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天浓瞪,我揣著相機與錄音懈玻,去河邊找鬼。 笑死乾颁,一個胖子當著我的面吹牛涂乌,可吹牛的內容都是我干的。 我是一名探鬼主播英岭,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼湾盒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了诅妹?” 一聲冷哼從身側響起罚勾,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎漾唉,沒想到半個月后荧库,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡赵刑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了场刑。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片般此。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖牵现,靈堂內的尸體忽然破棺而出铐懊,到底是詐尸還是另有隱情,我是刑警寧澤瞎疼,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布科乎,位于F島的核電站,受9級特大地震影響贼急,放射性物質發(fā)生泄漏茅茂。R本人自食惡果不足惜捏萍,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望空闲。 院中可真熱鬧令杈,春花似錦、人聲如沸碴倾。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跌榔。三九已至异雁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間僧须,已是汗流浹背纲刀。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留皆辽,地道東北人柑蛇。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像驱闷,于是被迫代替她去往敵國和親耻台。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內容