日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Java nio入門(mén)教程詳解(0033)

 360lec 2016-09-30

4.2 使用選擇鍵

讓我們看看SelectionKey類(lèi)的API:

  1. package java.nio.channels;
  2. public abstract class SelectionKey {
  3.     public static final int OP_READ
  4.     public static final int OP_WRITE
  5.     public static final int OP_CONNECT
  6.     public static final int OP_ACCEPT
  7.     public abstract SelectableChannel channel();
  8.     public abstract Selector selector();
  9.     public abstract void cancel();
  10.     public abstract boolean isValid();
  11.     public abstract int interestOps();
  12.     public abstract void interestOps(int ops);
  13.     public abstract int readyOps();
  14.     public final boolean isReadable()
  15.     public final boolean isWritable()
  16.     public final boolean isConnectable()
  17.     public final boolean isAcceptable()
  18.     public final Object attach(Object ob)
  19.     public final Object attachment()
  20. }

就像之前提到的那樣,一個(gè)鍵表示了一個(gè)特定的通道對(duì)象和一個(gè)特定的選擇器對(duì)象之間的注冊(cè)關(guān)系 。 您可以看到前兩個(gè)方法中反映了這種關(guān)系 。 channel()方法返回與該鍵相關(guān)的SelectableChannel對(duì)象,而selector()則返回相關(guān)的Selector對(duì)象。這沒(méi)有什么令人驚奇的。

鍵對(duì)象表示了一種特定的注冊(cè)關(guān)系。當(dāng)應(yīng)該終結(jié)這種關(guān)系的時(shí)候,可以調(diào)用SelectionKey對(duì)象的cancel()方法??梢酝ㄟ^(guò)調(diào)用isValid()方法來(lái)檢查它是否仍然表示一種有效的關(guān)系。當(dāng)鍵被取消時(shí),它將被放在相關(guān)的選擇器的已取消的鍵的集合里。注冊(cè)不會(huì)立即被取消,但鍵會(huì)立即失效(參見(jiàn) 4.3 節(jié))。當(dāng)再次調(diào)用select()方法時(shí)(或者一個(gè)正在進(jìn)行的select()調(diào)用結(jié)束時(shí)),已取消的鍵的集合中的被取消的鍵將被清理掉,并且相應(yīng)的注銷(xiāo)也將完成。通道會(huì)被注銷(xiāo),而新的SelectionKey將被返回。

當(dāng)通道關(guān)閉時(shí),所有相關(guān)的鍵會(huì)自動(dòng)取消(記住,一個(gè)通道可以被注冊(cè)到多個(gè)選擇器上)。當(dāng)選擇器關(guān)閉時(shí),所有被注冊(cè)到該選擇器的通道都將被注銷(xiāo),并且相關(guān)的鍵將立即被無(wú)效化(取消)。一旦鍵被無(wú)效化,調(diào)用它的與選擇相關(guān)的方法就將拋出CancelledKeyException。

一個(gè)SelectionKey對(duì)象包含兩個(gè)以整數(shù)形式進(jìn)行編碼的比特掩碼:一個(gè)用于指示那些通道/選擇器組合體所關(guān)心的操作(instrest集合),另一個(gè)表示通道準(zhǔn)備好要執(zhí)行的操作(ready集合)。當(dāng)前的interest集合可以通過(guò)調(diào)用鍵對(duì)象的interestOps()方法來(lái)獲取。最初,這應(yīng)該是通道被注冊(cè)時(shí)傳進(jìn)來(lái)的值。這個(gè)interset集合永遠(yuǎn)不會(huì)被選擇器改變,但您可以通過(guò)調(diào)用interestOps()方法并傳入一個(gè)新的比特掩碼參數(shù)來(lái)改變它。interest集合也可以通過(guò)將通道注冊(cè)到選擇器上來(lái)改變(實(shí)際上使用一種迂回的方式調(diào)用interestOps()),就像 4.1.2 小節(jié)中描的那樣。當(dāng)相關(guān)的Selector上的select()操作正在進(jìn)行時(shí)改變鍵的interest集合,不會(huì)影響那個(gè)正在進(jìn)行的選擇操作。所有更改將會(huì)在select()的下一個(gè)調(diào)用中體現(xiàn)出來(lái)。

可以通過(guò)調(diào)用鍵的readyOps()方法來(lái)獲取相關(guān)的通道的已經(jīng)就緒的操作。ready集合是interest集合的子集,并且表示了interest 集合中從上次調(diào)用 select()以來(lái)已經(jīng)就緒的那些操作。例如,下面的代碼測(cè)試了與鍵關(guān)聯(lián)的通道是否就緒。如果就緒,就將數(shù)據(jù)讀取出來(lái),寫(xiě)入一個(gè)緩沖區(qū),并將它送到一個(gè)consumer(消費(fèi)者)方法中。

  1. if ((key.readyOps() & SelectionKey.OP_READ) != 0){
  2.     myBuffer.clear();
  3.     key.channel().read(myBuffer);
  4.     doSomethingWithBuffer(myBuffer.flip());
  5. }

就像之前提到過(guò)的那樣,有四個(gè)通道操作可以被用于測(cè)試就緒狀態(tài)。您可以像上面的代碼那樣,通過(guò)測(cè)試比特掩碼來(lái)檢查這些狀態(tài),但SelectionKey類(lèi)定義了四個(gè)便于使用的布爾方法來(lái)為您測(cè)試這些比特值:isReadable(),isWritable(),isConnectable(), 和 isAcceptable()。每一個(gè)方法都與使用特定掩碼來(lái)測(cè)試readyOps()方法的結(jié)果的效果相同。例如:

if (key.isWritable())

等價(jià)于:

if ((key.readyOps() & SelectionKey.OP_WRITE) != 0)

這四個(gè)方法在任意一個(gè)SelectionKey對(duì)象上都能安全地調(diào)用。不能在一個(gè)通道上注冊(cè)一個(gè)它不支持的操作,這種操作也永遠(yuǎn)不會(huì)出現(xiàn)在ready集合中。調(diào)用一個(gè)不支持的操作將總是返回false,因?yàn)檫@種操作在該通道上永遠(yuǎn)不會(huì)準(zhǔn)備好。

需要注意的是,通過(guò)相關(guān)的選擇鍵的readyOps()方法返回的就緒狀態(tài)指示只是一個(gè)提示,不是保證。底層的通道在任何時(shí)候都會(huì)不斷改變。其他線(xiàn)程可能在通道上執(zhí)行操作并影響它的就緒狀態(tài)。同時(shí),操作系統(tǒng)的特點(diǎn)也總是需要考慮的。

SelectionKey對(duì)象包含的ready集合與最近一次選擇器對(duì)所注冊(cè)的通道所作的檢查相同。而每個(gè)單獨(dú)的通道的就緒狀態(tài)會(huì)同時(shí)改變。

您可能會(huì)從SelectionKey的API中注意到盡管有獲取ready集合的方法,但沒(méi)有重新設(shè)置那個(gè)集合的成員方法。事實(shí)上,您不能直接改變鍵的ready集合。在下一節(jié)里,也就是描述選擇過(guò)程時(shí),我們將會(huì)看到選擇器和鍵是如何進(jìn)行交互,以提供實(shí)時(shí)更新的就緒指示的。

讓我們?cè)囼?yàn)一下SelectionKey的API中剩下的兩個(gè)方法:

  1. public abstract class SelectionKey {
  2.     // 這里僅列出部分API
  3.     public final Object attach (Object ob)
  4.     public final Object attachment()
  5. }

這兩個(gè)方法允許您在鍵上放置一個(gè)「附件」,并在后面獲取它。這是一種允許您將任意對(duì)象與鍵關(guān)聯(lián)的便捷的方法。這個(gè)對(duì)象可以引用任何對(duì)您而言有意義的對(duì)象,例如業(yè)務(wù)對(duì)象、會(huì)話(huà)句柄、其他通道等等。這將允許您遍歷與選擇器相關(guān)的鍵,使用附加在上面的對(duì)象句柄作為引用來(lái)獲取相關(guān)的上下文。

attach()方法將在鍵對(duì)象中保存所提供的對(duì)象的引用。SelectionKey類(lèi)除了保存它之外,不會(huì)將它用于任何其他用途。任何一個(gè)之前保存在鍵中的附件引用都會(huì)被替換??梢允褂?code>null值來(lái)清除附件??梢酝ㄟ^(guò)調(diào)用attachment()方法來(lái)獲取與鍵關(guān)聯(lián)的附件句柄。如果沒(méi)有附件,或者顯式地通過(guò)null方法進(jìn)行過(guò)設(shè)置,這個(gè)方法將返回null。

如果選擇鍵的存續(xù)時(shí)間很長(zhǎng),但您附加的對(duì)象不應(yīng)該存在那么長(zhǎng)時(shí)間,請(qǐng)記得在完成后清理附件。否則,您附加的對(duì)象將不能被垃圾回收,您將會(huì)面臨內(nèi)存泄漏問(wèn)題。

SelectableChannel類(lèi)的一個(gè)register()方法的重載版本接受一個(gè)Object類(lèi)型的參數(shù)。這是一個(gè)方便您在注冊(cè)時(shí)附加一個(gè)對(duì)象到新生成的鍵上的方法。以下代碼:

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

等價(jià)于:

  1. SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
  2. key.attach (myObject);

關(guān)于SelectionKey的最后一件需要注意的事情是并發(fā)性??傮w上說(shuō),SelectionKey對(duì)象是線(xiàn)程安全的,但知道修改interest集合的操作是通過(guò)Selector對(duì)象進(jìn)行同步的是很重要的。這可能會(huì)導(dǎo)致interestOps()方法的調(diào)用會(huì)阻塞不確定長(zhǎng)的一段時(shí)間。選擇器所使用的鎖策略(例如是否在整個(gè)選擇過(guò)程中保持這些鎖)是依賴(lài)于具體實(shí)現(xiàn)的。幸好,這種多元處理能力被特別地設(shè)計(jì)為可以使用單線(xiàn)程來(lái)管理多個(gè)通道。被多個(gè)線(xiàn)程使用的選擇器也只會(huì)在系統(tǒng)特別復(fù)雜時(shí)產(chǎn)生問(wèn)題。坦白地說(shuō),如果您在多線(xiàn)程中共享選擇器時(shí)遇到了同步的問(wèn)題,也許您需要重新思考一下您的設(shè)計(jì)。

我們已經(jīng)探討了SelectionKey的 API,但我們還沒(méi)有談完選擇鍵的一切——遠(yuǎn)遠(yuǎn)沒(méi)有。讓我們進(jìn)一步了解如何使用選擇器管理鍵吧。

Java nio入門(mén)教程詳解(三十四)

0 0
我們認(rèn)為:用戶(hù)的主要目的,是為了獲取有用的信息,而不是來(lái)點(diǎn)擊廣告的。因此本站將竭力做好內(nèi)容,并將廣告和內(nèi)容進(jìn)行分離,確保所有廣告不會(huì)影響到用戶(hù)的正常閱讀體驗(yàn)。用戶(hù)僅憑個(gè)人意愿和興趣愛(ài)好點(diǎn)擊廣告。
我們堅(jiān)信:只有給用戶(hù)帶來(lái)價(jià)值,用戶(hù)才會(huì)給我們以回報(bào)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多