日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

完全理解NIO Selector

發(fā)布時(shí)間:2025/3/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 完全理解NIO Selector 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、Selector是什么

Selector是一個(gè)或多個(gè)SelectableChannel對(duì)象的多路復(fù)用器.

二、如何創(chuàng)建一個(gè)Selector對(duì)象

  • 一個(gè)selector對(duì)象可以通過(guò)調(diào)用Selector.open()來(lái)創(chuàng)建,這個(gè)工廠方法會(huì)使用系統(tǒng)默認(rèn)的selector provider來(lái)創(chuàng)建一個(gè)新的selector對(duì)象。或者我們還可以通過(guò)實(shí)現(xiàn)抽象類(lèi)SelectorProvider自定義一個(gè)selector provider,然后調(diào)用它的openSelector()來(lái)創(chuàng)建, 例如:new SelectorProviderImpl().openSelector()
  • 除非調(diào)用selector.close(),否則該selector將會(huì)一直保持打開(kāi)狀態(tài)。
  • 三、如何將selectable channel注冊(cè)到selector中

    SelectionKey key = channel.register(selector,Selectionkey.XXX);
  • 通過(guò)channel的register方法,將channel注冊(cè)到給定的selector中,并返回一個(gè)表示注冊(cè)關(guān)系的SelectionKey對(duì)象。
  • 四、selector如何維護(hù)selection keys

    一個(gè)selector維護(hù)著三個(gè)selection keys集合:

  • key set包含著所有selectionKeys,當(dāng)前所有注冊(cè)到selector中的channel返回的注冊(cè)關(guān)系SelectionKey都包含在內(nèi),這個(gè)集合可以通過(guò)selector.keys()方法返回。
  • selected-key set 包含著一部分selectionKeys,其中的每個(gè)selectionKey所關(guān)聯(lián)的channel在selectionoperation期間被檢測(cè)出至少準(zhǔn)備好了一個(gè)可以在興趣集中匹配到的操作。這個(gè)集合可以通過(guò)調(diào)用selector.selectedKeys()方法返回。
  • selected-keyset 一定是 key set 的子集。 cancelled-key set也包含著一部分selectionKeys,其中的每個(gè)selectionKey都已經(jīng)被取消,但是所關(guān)聯(lián)channel還沒(méi)有被撤銷(xiāo)登記。cancelled-key set 不能夠被直接返回,但也一定是 key set 的子集。
  • 對(duì)于一個(gè)新創(chuàng)建的selector其中這三個(gè)集合都是空著的。

  • 通過(guò)channel的register方法,一個(gè)selectionKey被增加到selector的 key set 中。
  • 無(wú)論通過(guò)channel.close()還是通過(guò)selectionKey.cancel()來(lái)取消一個(gè)selectionKey ,這個(gè)selectionKey都會(huì)被立即添加到selector的 cancelled-key set中,但是所關(guān)聯(lián)的channel并沒(méi)有立即被撤銷(xiāo)登記,直到發(fā)生下次 selection operations,這些channel才被從selector中撤銷(xiāo)登記,與此同時(shí)這些Cancelled keys才會(huì)被從這個(gè)selector的所有selectionKey set(可能是_key set_、selected-key set、cancelled-key set)中移除,但是不會(huì)影響這些集合本身。
  • 在 selection operations 期間,一些selectionKey會(huì)被選中添加到 selected-key set 中。其中的每個(gè)key可以通過(guò)selectiedKeys.remove()或selectiedKeys.iterator().remove()直接從 selected-key set 中移除,除此之外不能夠通過(guò)任何方式被直接移除。特殊的,selected-key set 中的keys還可以在 selection operations 期間被間接移除。但是是不可以直接向 selected-key set 添加key的。
  • 五、selector如何選擇就緒channel

    • 每次 selection operation 期間, keys都可以添加到或從selector’s selected-key set 被移除,同時(shí)也可- 以從它的 key 和 cancelled-key sets 被移除。 selection operation 可以被觸發(fā)通過(guò)執(zhí)行selector.select(),selector.select(long),和selector.selectNow() 方法,并且這些方法涉及到以下三個(gè)步驟:
  • 首先每個(gè)位于 cancelled-key set
    中的key會(huì)從每個(gè)包含它的key集合中被移除,并且對(duì)應(yīng)的channel會(huì)被撤銷(xiāo)登記。這個(gè)步驟使得 cancelled-key set
    變?yōu)榭铡?/p>

  • 查詢底層操作系統(tǒng)來(lái)獲得關(guān)于selector中剩余channel的就續(xù)事件從 selection operation
    開(kāi)始截止到此刻的更新情況,只要哪個(gè)channel的就續(xù)事件的更新部分有至少一個(gè)與興趣集中的操作匹配上,那么將會(huì)執(zhí)行以下兩個(gè)動(dòng)作:

  • 如果這個(gè)channel’s key 沒(méi)有存在 于 selected-key set
    那么將它添加到這個(gè)集合中,并將它的就緒操作集(ready-operation set)修改成
    只包含使得channel被報(bào)告就緒的操作,任何先前記錄在就緒操作集中的就緒信息都會(huì)被丟棄。
  • 否則,如果這個(gè)channel’s key 存在 于 selected-key set ,那么就保留就緒操作集中先前的就緒信息,并將這些
    使得channel被報(bào)告就緒的操作 寫(xiě)入進(jìn)去;總而言之,系統(tǒng)底層會(huì)通過(guò)按位與&操作更新當(dāng)前就緒集。
  • 如果這些Key的興趣集為空,那么 selected-key set 和 keys’的就續(xù)集(ready-operation
    sets)都不會(huì)被更新。
  • 如果在步驟(2)正在進(jìn)行時(shí)將任何key添加到 cancelled-key set,則按步驟(1)處理它們。
    • selection operations 是否會(huì)阻塞等待一個(gè)或多個(gè)通道準(zhǔn)備就緒,以及等待多長(zhǎng)時(shí)間,這是三種選擇方法之間唯一的本質(zhì)區(qū)別。

    六、selector線程安全嗎

    多線程并發(fā)情況下Selectors本身是線程安全的,但是他們所持有的key sets不是線程安全的。

    selection operations 按順序在selector本身,key set 和 selected-key set 上同步。 它們還在上面的步驟(1)和(3)期間在 canceled-key set 上同步。

    在 selection operations 期間改變key的興趣集,對(duì)于本次操作將不會(huì)產(chǎn)生任何影響;它們的影響將會(huì)在下次 selection operations 期間發(fā)生。

    selectionKey可能會(huì)被取消,channel可能隨時(shí)關(guān)閉。 因此,在一個(gè)或多個(gè)選擇器的key集中存在并不意味著selectionKey有效或其channel是開(kāi)放的。有可能另一個(gè)線程取消selectionKey或關(guān)閉一個(gè)channel,應(yīng)用程序代碼應(yīng)該小心地同步并檢查這些條件。

    一個(gè)線程通過(guò)selector.select()或selector.select(long)方法產(chǎn)生的阻塞可以被其他線程用以下三種方式的任意一種來(lái)中斷:

  • By invoking the selector’s wakeup() method,

  • By invoking the selector’s close() method, or

  • By invoking the blocked thread’s interrupt() method, in which case itsinterrupt status will be set and the selector’s wakeup() method will
    be invoked.

  • selector.close() 在 selection operations 期間會(huì)順序的同步selectorand all three key sets 。

    一個(gè)selector的 key set 和 selected-key set 通常情況下是線程不安全的。如果一個(gè)線程想要修改這個(gè)集合,需要同步控制它。通過(guò)key集合的iterator()方法返回的Iterators提供了快速失敗(fail-fast):如果在創(chuàng)建迭代器之后修改了set,除了通過(guò)調(diào)用迭代器自己的remove() 方法之外,將拋出ConcurrentModificationException 。

    文章轉(zhuǎn)自

    總結(jié)

    以上是生活随笔為你收集整理的完全理解NIO Selector的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。