2011-11-20 6 views
6

を起きていない再利用します。このコードを実行した後、netstatをチェックすると、10のTCP接続が開いているのがわかります。私は接続が再利用されることを期待していました。どうしてこれなの ?何か不足していますか?は、HTTPClientは4.xの接続は、Iは、Apache HTTPクライアントの次の例を試してみました

コードスニペットは以下の通りです:

public class ClientMultiThreadedExecution { 
public static void main(String[] args) throws Exception { 

    SchemeRegistry schemeRegistry = new SchemeRegistry(); 
    schemeRegistry.register(
    new Scheme("http", 18080, PlainSocketFactory.getSocketFactory())); 

    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(schemeRegistry); 
    cm.setDefaultMaxPerRoute(5); 
    cm.setMaxTotal(5); 


    HttpClient httpclient = new DefaultHttpClient(cm); 
    try { 
     // create an array of URIs to perform GETs on 
     String uri = "http://test.webservice.com:18080/TestServlet"; 
     String data = "This is a test message"; 

     System.out.println("Started at: " + new Date()); 
     // creating 10 threads 
     PostThread[] threads = new PostThread[10]; 

     for (int i = 0; i < threads.length; i++) { 
     HttpPost httpPost = new HttpPost(uri); 
     threads[i] = new PostThread(httpclient, httpPost, data, i + 1); 
      threads[i].start(); 
      //Thread.sleep(1000); 
     } 

     // join the threads 
     for (int j = 0; j < threads.length; j++) { 
      threads[j].join(); 
     } 

    } finally { 
     // When HttpClient instance is no longer needed, 
     // shut down the connection manager to ensure 
     // immediate deallocation of all system resources 
     System.out.println("Ended at: " + new Date()); 
     httpclient.getConnectionManager().shutdown(); 
    } 
} 

/** 
* A thread that performs a POST. 
*/ 
static class PostThread extends Thread { 

    private final HttpClient httpClient; 
    private final HttpContext context; 
    private final HttpPost httpPost; 
    private final int id; 
    private final String data; 

    public PostThread(HttpClient httpClient, HttpPost httpPost, String data, int id) { 
     this.httpClient = httpClient; 
     this.context = new BasicHttpContext(); 
     this.httpPost = httpPost; 
     this.id = id; 
     this.data = data; 
    } 

    /** 
    * Executes the PostMethod and prints some status information. 
    */ 
    @Override 
    public void run() { 

     //System.out.println(id + " - about to get something from " + httpPost.getURI()); 

     try { 

      List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1); 
      nameValuePairs.add(new BasicNameValuePair("XML",data)); 
      httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8")); 

      // execute the method 
      HttpResponse response = httpClient.execute(httpPost, context); 

      //System.out.println(id + " - get executed"); 
      // get the response body as an array of bytes 
      if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) 
       System.out.println("Success"); 

      //Is this step necessary ?? Need to check as only status code is required 
      //httpPost.abort(); 
      //HttpEntity entity = response.getEntity(); 

      //And this ? 
      //EntityUtils.consume(entity); 

     } catch (Exception e) { 
      httpPost.abort(); 
      System.out.println(id + " - error: " + e); 
     } 
    } 

}} 
+1

溶液は、具体的にHTTP_1_1としてプロトコルバージョン言及した: 'HttpProtocolParams.setVersion(paramsは、HttpVersion.HTTP_1_1)と、'。その後プールしました。 – Dunxton

+0

paramsの代わりに何を保存する必要があるのか​​は、どのような価値があり、コード内にこのステートメントを置く必要があるかを意味します。 – Labeo

答えて

11

 //Is this step necessary ?? Need to check as only status code is required 
     //httpPost.abort(); 
     //HttpEntity entity = response.getEntity(); 

     //And this ? 
     //EntityUtils.consume(entity); 

は何を思いますか?そうです。

一つ応答内容が接続マネージャに解放基になる接続を持つために消費されますことを確認しなければなりません。 EntityUtils#consumeまたはhttpUriRequest#abortのいずれかを呼び出すと、プールへの接続が解除されます。違いは、前者が接続を維持しようとしているのに対し、後者は接続を維持しようとしている点です。このコードで

+0

このコードブロックはどうですか? 'catch(例外e){ httpPost.abort(); System.out.println(id + " - エラー:" + e); } '例外が発生するたびに、httpPost.abort()が呼び出されます。しかし、私が観察することは、同じアボートされた接続が他のスレッドに引き渡されており、それらのすべてが 'java.io.IOException:Request has aborted'というメッセージでエラーになることです。なぜこれが起こるのですか? – Dunxton

+2

@Dunxton中止された接続は破棄され、すぐにプールから削除されます。中止されたリクエストを再利用しようとしています。そんなことしたらダメ。リクエストオブジェクトは安価です。 – oleg

関連する問題