簡體   English   中英

Java - 用於非阻塞套接字的多個線程中的多個選擇器

[英]Java - Multiple selectors in multiple threads for nonblocking sockets

我正在編寫一個Java應用程序,它將實例化一個類的對象,以表示已在我的應用程序的另一端連接並注冊到外部系統的客戶端。

每個客戶端對象都有兩個嵌套類,表示前端和后端。 前端類將不斷從實際客戶端接收數據,並將指示和數據發送到后端類,后端類將從前端獲取數據並使用適當的格式和協議將其發送到外部系統該系統需要。

在設計中,我們希望將客戶端對象的每個實例化都作為一個線程。 然后,在每個線程中自然會有兩個插槽[編輯],每個插槽都有自己的NIO通道[/ EDIT],一個客戶端,一個系統端分別位於前端和后端。 但是,這現在引入了對非阻塞套接字的需求。 我一直在閱讀這里的教程,解釋如何在主線程中安全地使用Selector來處理所有帶連接的線程。

但是,我需要的是多個選擇器 - 每個選擇器都在自己的線程中運行。 通過閱讀上述教程,我了解到Selector中的鍵集不是線程安全的。 這是否意味着在我們自己的repsective線程中實例化的單獨選擇器可能會創建沖突的密鑰,如果我嘗試給它們各自的一對套接字和通道? 將選擇器移動到主線程的可能性很小,但根據我已經給出的軟件要求,它遠非理想。 謝謝您的幫助。

如果必須使用此單插槽連接,則必須將數據與數據處理本身的數據接收和寫入過程分開。 您不必委派頻道。 通道就像一輛公共汽車。 總線(管理通道的單線程)必須讀取數據並將其寫入(線程安全的)輸入隊列,包括所需的信息,因此您的客戶端線程可以從中獲取正確的數據報包。隊列。 如果客戶端線程喜歡寫入數據,那么該數據將被寫入輸出隊列,然后由通道線程讀取以將數據寫入通道。

因此,從使用此連接的actor之間的連接與不可預測的處理時間(這是塊的主要原因)共享連接的概念,您將轉向異步數據讀取,數據處理和數據寫入的概念。 因此,處理時間不再是不可預測的,而是時間,您的數據被讀取或寫入。 非阻塞意味着盡管處理該數據需要時間,但數據流盡可能保持不變。

只要您沒有在兩個選擇器實例中注冊具有相同興趣(OP_READ / OP_WRITE等)的相同通道,使用多個選擇器就可以了。 使用多個選擇器實例注冊相同的通道可能會導致selector1.select()可能使用selector2.select()可能感興趣的事件的問題。

大多數平台上的默認選擇器都是poll()[或epoll()]。

Selector.select在內部調用int poll( ListPointer, Nfdsmsgs, Timeout) method.

        where the ListPointer structure can then be initialized as follows:

    list.fds[0].fd = file_descriptorA;
    list.fds[0].events = requested_events;
    list.msgs[0].msgid = message_id;
    list.msgs[0].events = requested_events;

也就是說,我建議使用ROX RPC nio教程中提到的單個選擇線程。 NIO實現依賴於平台,很可能在一個平台上工作的東西可能不適用於另一個平台。 我也看到了次要版本的問題。 例如,AIX JDK 1.6 SR2使用基於poll()的選擇器 - PollSelectorImpl和相應的選擇器提供程序作為PollSelectorProvider,我們的服務器運行正常。 當我轉移到使用基於pollset接口的優化選擇器(PollSetSelectorImpl)的AIX JDK 1.6 SR5時,我們在select()和socketchannel.close()中遇到了頻繁掛起的服務器。 其中一個原因我看到的是,我們在我們的應用程序中打開多個選擇(而不是理想選擇一個線程模型)和描述的PollSetSelectorImpl實行這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM