4.3.4并發(fā)性 選擇器對象是線程安全的,但它們包含的鍵集合不是。通過keys()和selectKeys()返回的鍵的集合是Selector對象內(nèi)部的私有的Set對象集合的直接引用。這些集合可能在任意時間被改變。已注冊的鍵的集合是只讀的。如果您試圖修改它,那么您得到的獎品將是一個java.lang.UnsupportedOperationException,但是當您在觀察它們的時候,它們可能發(fā)生了改變的話,您仍然會遇到麻煩。Iterator對象是快速失敗的(fail-fast):如果底層的Set被改變了,它們將會拋出java.util.ConcurrentModificationException,因此如果您期望在多個線程間共享選擇器和/或鍵,請對此做好準備。您可以直接修改選擇鍵,但請注意您這么做時可能會徹底破壞另一個線程的Iterator。 如果在多個線程并發(fā)地訪問一個選擇器的鍵的集合的時候存在任何問題,您可以采取一些步驟來合理地同步訪問。在執(zhí)行選擇操作時,選擇器在Selector對象上進行同步,然后是已注冊的鍵的集合,最后是已選擇的鍵的集合,按照這樣的順序。已取消的鍵的集合也在選擇過程的的第1步和第3步之間保持同步(當與已取消的鍵的集合相關(guān)的通道被注銷時)。 在多線程的場景中,如果您需要對任何一個鍵的集合進行更改,不管是直接更改還是其他操作帶來的副作用,您都需要首先以相同的順序,在同一對象上進行同步。鎖的過程是非常重要的。如果競爭的線程沒有以相同的順序請求鎖,就將會有死鎖的潛在隱患。如果您可以確保否其他線程不會同時訪問選擇器,那么就不必要進行同步了。 Selector類的close()方法與slect()方法的同步方式是一樣的,因此也有一直阻塞的可能性。在選擇過程還在進行的過程中,所有對close()的調(diào)用都會被阻塞,直到選擇過程結(jié)束,或者執(zhí)行選擇的線程進入睡眠。在后面的情況下,執(zhí)行選擇的線程將會在執(zhí)行關(guān)閉的線程獲得鎖是立即被喚醒,并關(guān)閉選擇器(參見4.3.2小節(jié))。 Java nio入門教程詳解(三十八) 00 我們認為:用戶的主要目的,是為了獲取有用的信息,而不是來點擊廣告的。因此本站將竭力做好內(nèi)容,并將廣告和內(nèi)容進行分離,確保所有廣告不會影響到用戶的正常閱讀體驗。用戶僅憑個人意愿和興趣愛好點擊廣告。 我們堅信:只有給用戶帶來價值,用戶才會給我們以回報。 |
|