2011-11-15 1 views
7
public class test { 
    public static final int nThreads = 2; 

    public static void main(String[] args) throws ExecutionException, InterruptedException{ 
    // Runnable myrunnable = new myRunnable(); 
     ExecutorService execute = Executors.newFixedThreadPool(nThreads); 

     for (int i = 0; i < nThreads; ++i) { 
      execute.execute(new MyTask()); 
     }   

     execute.awaitTermination(1000, TimeUnit.MILLISECONDS); 

     execute.shutdown(); 
    } 
} 

class MyTask implements Runnable { 
    public static final int maxCalls = 10; 
    public static final int sleepMillis = 500; 
    private static HttpResponse response; 
    private static HttpClient httpclient; 

    public void run(){ 
     int counter = 0; 

     while (true) { 

      if (counter >= maxCalls) { 
       break; 
      } 
      try { 
       Thread.currentThread().sleep(sleepMillis); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      execHttpRequest(); 

      ++counter; 
     } 
    } 

    private void execHttpRequest() { 
     httpclient = new DefaultHttpClient(); 
     HttpGet httpget = new HttpGet("My URL"); 

     try { 

      response = httpclient.execute(httpget); 
      BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
      String output; 
      while((output=br.readLine())!=null){ 
       System.out.println(Thread.currentThread().getName() +output); 
      } 
      br.close(); 

      httpclient.getConnectionManager().shutdown(); 
      //httpclient.getConnectionManager().shutdown(); 
     } catch (ClientProtocolException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     finally{ 

      httpclient.getConnectionManager().shutdown(); 
     } 

    } 


} 

このコードを実行している間、私は次の例外を取得:私は、HTTPリクエストを実行するとマルチスレッドHttpClientを

Exception in thread "pool-1-thread-1" java.lang.IllegalStateException: Invalid use of SingleClientConnManager: connection still allocated. 
Make sure to release the connection before allocating another one. 
    at org.apache.http.impl.conn.SingleClientConnManager.getConnection(SingleClientConnManager.java:216) 
    at org.apache.http.impl.conn.SingleClientConnManager$1.getConnection(SingleClientConnManager.java:190) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:401) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) 
    at MyTask.execHttpRequest(test.java:72) 
    at MyTask.run(test.java:60) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:722) 
java.io.InterruptedIOException: Connection has been shut down 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:543) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754) 
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:732) 
    at MyTask.execHttpRequest(test.java:72) 
    at MyTask.run(test.java:60) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) 
    at java.lang.Thread.run(Thread.java:722) 
Caused by: org.apache.http.impl.conn.ConnectionShutdownException 
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.assertValid(AbstractPooledConnAdapter.java:86) 
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.getRoute(AbstractPooledConnAdapter.java:112) 
    at org.apache.http.impl.client.DefaultRequestDirector.establishRoute(DefaultRequestDirector.java:740) 
    at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:577) 
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:425) 
    ... 8 more 

を、私はこれらの例外を参照してください。これは、シングルスレッドのために完璧に動作します。特定のURL(完全に正常に動作します)を呼び出そうとしていますが、複数のスレッドを追加すると、不正な状態の例外がスローされます。

+1

スタックトレースを読むことを学びます。 – mre

答えて

3

を見ることができます詳細については

MultiThreadedHttpConnectionManager connectionManager = 
            new MultiThreadedHttpConnectionManager(); 
HttpClient client = new HttpClient(connectionManager); 

! httpClientとhttpRequestはどちらも静的です。私はそれらを非静的にした後、正常に動作します!エグゼキュータサービスは私にスレッド管理のより良いコントロールを与え、私はそれを利用したいと思っていました。

7

ここで、MultiThreadedHttpConnectionManagerは古くなっています。現在(のHttpClientバージョン4. *)これは方法です。またhttp://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d5e639

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

ClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry); 
HttpClient httpClient = new DefaultHttpClient(cm); 
1

答えのbpgergoする - 接続マネージャが(HttpClientをバージョン> = 4.3のように)再び更新しており、今あなたがPoolingHttpClientConnectionManagerを使用する必要がありますが代わりに。 PoolingHttpClientConnectionManagerのデフォルトの制限は合計20の接続と1つのルートで2つですが、これらはオーバーライドできます。

PoolingHttpClientConnectionManager cm=new PoolingHttpClientConnectionManager(); 
cm.setDefaultMaxPerRoute(40); 
cm.setMaxTotal(500); 
CloseableHttpClient client = HttpClients.createMinimal(cm);