2014-10-03 73 views
0

我有一個簡單的客戶端服務器應用程序使用套接字進行通信。一種可能性是每次客戶端向服務器發送一些東西時關閉套接字。保持java套接字打開 - 如何檢查新數據是否可用?

但我的想法是保持連接始終打開,即如果客戶端聯繫服務器,應將連接放入隊列(例如LinkedBlockingQueue)並保持打開狀態,這會提高性能。

如何在服務器中檢查隊列中是否有可用的新數據?我能想象的唯一事情就是不斷迭代整個隊列,並檢查每個套接字是否有新數據。但是這會非常低效,因爲如果我有幾個線程在隊列上工作,當一個線程掃描隊列時隊列就會被阻塞。

或者是否有可能在套接字上註冊回調函數,以便套接字通知線程數據已準備好?

+0

套接字的InputStreams有幾個讀取方法,可以阻止當前線程,直到有可用的東西。你通常需要做套接字網絡多線程。這意味着每個客戶端都有一個接收線程,將數據存儲在主線程需要時可以檢索到的地方。 (評論,因爲不知道這是否是這個問題) – Felk 2014-10-03 23:16:55

回答

2

但我的想法是保持連接始終打開,即如果客戶端聯繫服務器,連接應放入隊列(例如LinkedBlockingQueue)並保持打開狀態,則會提高性能。

保持連接打開將提高性能,儘管存在擴展問題:打開的套接字使用內核資源。 (雖然我不會使用隊列...)

如何在服務器中檢查隊列中的套接字是否有新數據?

如果你有一個數量的插座不同客戶的,你要處理的(大致)訂單數據,它到來時,常見的有兩種方法:

  • 創建每一個線程套接字,並讓每個線程簡單地進行讀取。這將(自然)阻塞線程直到數據可用。

  • 使用NIO通道選擇器機制(請參閱Selector),該機制可讓您找出一組I/O通道中的哪一組準備好讀取或寫入。每個插槽

主題往往是耗資源(線程堆棧),並在所有的,如果你有多個線程同時處於活躍不能很好地擴展。 (上下文切換太多,線程調度器上的負載太多)。相比之下,選擇器映射到主機操作系統提供的本機系統調用,因此它們高效且響應...如果智能地使用。

(你也可以得到無阻塞通道的插槽,和他們進行輪詢循環的方式,但是這不會是任何有效的或有反應。)

正如你所看到的,沒有任何的這些想法與隊列一起工作。要麼你有多個線程處理一個套接字,要麼你有一個線程處理套接字的數組或(數組)列表。隊列抽象不是爲索引或迭代而設計的。

或者是否有可能在套接字上註冊回調函數,以便套接字通知線程數據已準備好?

查看@ Lolo的回答。

+0

感謝您的回答。假設我有一個在套接字線程接受連接時創建的線程。當線程現在將連接放到隊列中,然後線程終止時,這是否也會關閉連接? – machinery 2014-10-04 13:11:01

相關問題