這篇文章概括了怎樣在多線程環境下安全的使用HttpClient。
建立連接
在HttpClient中使用多線程的一個主要原因是可以一次執行多個方法。在執行期間,每一個方法都使用一個HttpConnection實例。由于在同一時間多個連接只能安全地用于單一線程和方法和有限的資源,我們就必須確保連接分配給正確的方法。而MultiThreadedHttpConnectionManager完全可以代替我們完成這一項工作,這樣我們就不必去考慮多線程帶來安全的問題。MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); HttpClient client = new HttpClient(connectionManager);以上代碼中的HttpClient就在多線程中執行多個方法了。當我們再次調用httpClient.executeMethod()方法時,就會去Connection Manager中去請求HttpConneciton的實例,這樣就避免了線程安全問題,因為HttpClient已經幫我們做了。
釋放連接
Connection Management比較重要的是當連接不再使用時,一定要手動釋放。這樣做的原因是HttpClient不能夠確定哪個方法不被使用,哪個方法還在使用。這是因為Response body不是由HttpClient來自動讀取其數據的,而是由使用HttpClient的應用程序來完成的。當讀取Response的數據是時,必須使用此方法的連接。這樣,在Response的數據在讀取前,HttpClient是沒有釋放連接的。所有這就要求在讀取完Response的數據后,應用程序及時的使用releaseConnection()方法來釋放連接。特別注意,無論執行的方法或是否也不例外被拋出。對于每一個HttpClient.executeMethod方法必須有一個method.releaseConnection ( )來釋放連接。
重用HttpClient實例
一般說來,建議一個通訊組件,甚至說一個應用軟件就始終維持一個HttpClient對象實例存在。但是如果你的應用很稀罕才用到它,而且還不允許這么一個實例一直存在,那么,這里強烈建議,一定要顯式地shut down 它的MultiThreadedHttpConnectionManager 。這樣做是確保連接池里的Connection得到釋放。
HttpMethod并發執行
如果應用程序邏輯允許并發執行多個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。
新聞熱點
疑難解答