HttpClient多線程併發問題

這篇文章歸納了怎樣在多線程環境下安全的使用HttpClient。緩存

創建鏈接
安全

        在HttpClient中使用多線程的一個主要緣由是能夠一次執行多個方法。在執行期間,每個方法都使用一個HttpConnection實例。因爲在同一時間多個鏈接只能安全地用於單一線程和方法和有限的資源,咱們就必須確保鏈接分配給正確的方法。而MultiThreadedHttpConnectionManager徹底能夠代替咱們完成這一項工做,這樣咱們就沒必要去考慮多線程帶來安全的問題。
MultiThreadedHttpConnectionManager connectionManager =
                 new MultiThreadedHttpConnectionManager();
          HttpClient client = new HttpClient(connectionManager);
服務器

以上代碼中的HttpClient就在多線程中執行多個方法了。當咱們再次調用httpClient.executeMethod()方法時,就會去Connection Manager中去請求HttpConneciton的實例,這樣就避免了線程安全問題,由於HttpClient已經幫咱們作了。網絡


釋放鏈接session

          Connection Management比較重要的是當鏈接再也不使用時,必定要手動釋放。這樣作的緣由是HttpClient不可以肯定哪一個方法不被使用,哪一個方法還在使用。這是由於Response body不是由HttpClient來自動讀取其數據的,而是由使用HttpClient的應用程序來完成的。當讀取Response的數據是時,必須使用此方法的鏈接。這樣,在Response的數據在讀取前,HttpClient是沒有釋放鏈接的。全部這就要求在讀取完Response的數據後,應用程序及時的使用releaseConnection()方法來釋放鏈接。特別注意,不管執行的方法或是否也不例外被拋出。對於每個HttpClient.executeMethod方法必須有一個method.releaseConnection ( )來釋放鏈接。多線程


重用HttpClient實例併發

          通常說來,建議一個通信組件,甚至說一個應用軟件就始終維持一個HttpClient對象實例存在。可是若是你的應用很稀罕纔用到它,並且還不容許這麼一個實例一直存在,那麼,這裏強烈建議,必定要顯式地shut down 它的MultiThreadedHttpConnectionManager 。這樣作是確保鏈接池裏的Connection獲得釋放。 
異步


HttpMethod併發執行socket

         若是應用程序邏輯容許併發執行多個HTTP請求,(例如對多個服務器的多個併發請求,或對同一個服務器表明不一樣用戶身份的多個請求) ,應用程序能夠爲每個HTTP session開啓一個專門的線程,這樣的設計天然將帶來顯著的性能提高。 而當使用一個線程安全的鏈接管理器MultiThreadedHttpConnectionManager 時,HttpClient能保證線程安全。這樣,多個線程能夠共享這麼一個線程安全的HttpClient實例。請注意,應用程序的每一個各自執行的線程必須使用各自的HttpMethod實例;而且可配置各自的HttpState實例和/或HostConfiguration實例(表明一個特定的會話狀態和主機配置)。這個共享的HttpClient和其標配的MultiThreadedHttpConnectionManager將爲各線程帶來最高的性能。
高併發


使用流來發送和接收數據

        HttpClient同時支持Stream和String/byte[]兩種方式來發送和接受數據,可是因爲String/byte[]的方式會形成內存中有一份數據的拷貝或緩存,那麼當請求或應答報文比較大,或者在高併發的應用中,使用String/byte[]就會形成額外的內存開銷,因此使用流的方式來傳輸數據是更好的選擇。


HttpClient的三種超時說明

/* 從鏈接池中取鏈接的超時時間 */ConnManagerParams.setTimeout(params, 1000);/* 鏈接超時 */HttpConnectionParams.setConnectionTimeout(params, 2000);/* 請求超時 */HttpConnectionParams.setSoTimeout(params, 4000); 第一行設置ConnectionPoolTimeout:這定義了從ConnectionManager管理的鏈接池中取出鏈接的超時時間,此處設置爲1秒。第二行設置ConnectionTimeout:  這定義了經過網絡與服務器創建鏈接的超時時間。Httpclient包中經過一個異步線程去建立與服務器的socket鏈接,這就是該socket鏈接的超時時間,此處設置爲2秒。第三行設置SocketTimeout:    這定義了Socket讀數據的超時時間,即從服務器獲取響應數據須要等待的時間,此處設置爲4秒。以上3種超時分別會拋出ConnectionPoolTimeoutException,ConnectionTimeoutException與SocketTimeoutException。

相關文章
相關標籤/搜索