對於練習,我們將實現一個服務器,該服務器具有偵聽連接的線程,接受它們並將套接字引入BlockingQueue。池中的一組工作線程然後通過隊列並處理通過套接字進入的請求。Java:使用隊列管理比線程更多的連接
每個客戶端連接到服務器,發送大量的請求(在發送下一個請求之前等待響應),並最終在完成時斷開連接。
我目前的方法是讓每個工作線程在隊列中等待,獲取套接字,然後處理一個請求,並最終將(仍然打開的)套接字放回隊列中,然後再處理另一個請求, 。有更多的客戶端比工作線程多,所以很多連接排隊。
此方法的問題:即使客戶端不發送任何內容,線程也會被客戶端阻止。可能的僞解決方案,都不能令人滿意:在inputStream
- 呼叫
available()
,並把連接回到隊列中,如果返回0的問題:這是不可能的檢測,如果客戶端仍連接。 - 如上所述,但使用
socket.isClosed()
或socket.isConnected()
來確定客戶端是否仍連接。問題:這兩種方法都沒有檢測到客戶端掛起,正如EJP在Java socket API: How to tell if a connection has been closed? - 中很好地描述的一樣,通過讀取或寫入客戶端來探測客戶端是否仍在那裏。問題:讀取塊(即回到非活動客戶端阻塞隊列的原始情況),並且寫入實際上會將某些內容發送給客戶端,從而使測試失敗。
有沒有辦法解決這個問題?即是否有可能區分一個斷開的客戶端與被動客戶端沒有阻止或發送的東西?
如果我理解正確,這個問題與阻塞IO無關,可用()中的問題用於解決這個問題。相反,問題在於如何判斷客戶是否意外關閉,或只是安靜。我認爲使用NIO對此並無幫助。 –
我試圖處理更大的查詢'這種方法的問題:即使客戶端不發送任何東西,線程也會被客戶端阻止。兩個模型都存在斷開連接的客戶端,但至少在NIO中,您並不等待它們。 – ptomli
同樣可以使用available()no?還沒有等待。 –