问题应该是出在httpClient上,所有线程共享一个全局的httpClient,这里估计出现资源竞争等待,所以超时了,你有没有试在不用全局的httpClient,而是像httpget一样,每个线程都new一个新的。

解决方案 »

  1.   

    3楼的说法比较有道理。虽然未必是资源竞争等待,但缺省的HttpClient确实不支持并发,这意味很多成员变量在并发使用过程中会互相影响。如果非要用想某些Cookie信息之类的而不能每个线程独立使用一个HttpClient,建议考虑用 ThreadSafeClientConnManager协助管理,释放方式不复杂,网上也有不少例子。ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager();  
    cm.setMaxTotal(50);  
    HttpClient httpclient = new DefaultHttpClient(cm);
      

  2.   

    LZ 用我这个  HTTPCLIENT 池试试
    package com.kanesoft.method.httppost;import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;import org.apache.http.HttpResponse;
    import org.apache.http.NameValuePair;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.entity.UrlEncodedFormEntity;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.conn.scheme.PlainSocketFactory;
    import org.apache.http.conn.scheme.Scheme;
    import org.apache.http.conn.scheme.SchemeRegistry;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
    import org.apache.http.message.BasicNameValuePair;
    import org.apache.http.params.BasicHttpParams;
    import org.apache.http.params.HttpConnectionParams;
    import org.apache.http.params.HttpParams;
    import org.apache.http.protocol.HTTP;public class MultiThreadedHttpConnection {
    private static HttpClient httpClient;
    private static final String contextType = "text/xml;charset=UTF-8";
    private static ExecutorService es = Executors.newFixedThreadPool(10);
    private static MultiThreadedHttpConnection mthc = new MultiThreadedHttpConnection();
    private static String url = "http://localhost:8000/2.php";
    private static int maxTotal = 300;
    private static int maxPerRout = 200;
    private static int connecttimeOut = 10000;
    private static int readTimeOut = 5000; static {
    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager();
    cm.setMaxTotal(maxTotal);
    cm.setDefaultMaxPerRoute(maxPerRout); HttpParams params = new BasicHttpParams();
    HttpConnectionParams.setConnectionTimeout(params, connecttimeOut);
    HttpConnectionParams.setSoTimeout(params, readTimeOut); httpClient = new DefaultHttpClient(cm, params); } private MultiThreadedHttpConnection() { } public static MultiThreadedHttpConnection getInstance() {
    return mthc;
    } public void httpAsyncSendByMap(final Map<String, String> map) {
    es.execute(new postThread(mthc, map));
    } private int sendDataByPost(Map<String, String> map) {
    Integer statusCode = -1;
    HttpPost post = new HttpPost(url);
    List<NameValuePair> nvps = new ArrayList<NameValuePair>();
    for (Map.Entry<String, String> m : map.entrySet()) {
    nvps.add(new BasicNameValuePair(m.getKey(), m.getValue()));
    }
    StringEntity entity;
    try {
    entity = new UrlEncodedFormEntity(nvps, HTTP.UTF_8);
    post.setEntity(entity);
    post.setHeader("Content-Type", contextType);
    HttpResponse response = httpClient.execute(post);
    statusCode = response.getStatusLine().getStatusCode();
    System.out.println(statusCode);
    if (statusCode != 200) {
    System.out.println("error quest");
    }
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    } catch (ClientProtocolException e) {
    e.printStackTrace();
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    post.abort();
    } return statusCode;
    } class postThread implements Runnable {
    private MultiThreadedHttpConnection m = null;
    private Map<String, String> map = null; public postThread(MultiThreadedHttpConnection m, Map<String, String> map) {
    this.m = m;
    this.map = map;
    } @Override
    public void run() {
    m.sendDataByPost(map);
    }
    } public static void main(String[] args) {
    for (int i = 0; i < 10000; i++) {
    Map<String, String> map = new HashMap<String, String>();
    map.put("vcode", 1 + "");
    map.put("sid", i + "");
    MultiThreadedHttpConnection.getInstance().httpAsyncSendByMap(map);
    }
    }
    }
      

  3.   

    每个线程单独使用 HttpClient 一样超时。
      

  4.   

    我今天也遇到了,原因是你请求的是同一个服务器下的不同页面,httpclient在你和服务器之间建立了一条路由,这个路由的最大并发连接数是2,所以当你开启多个线程并发请求的时候,就会出现连接不够用或者连接超时的问题,解决方法是这样的(红色为重点):
    HttpParams params = new BasicHttpParams();
    /* 从连接池中取连接的超时时间 */
    ConnManagerParams.setTimeout(params, 10000);
    /* 连接超时 */
    HttpConnectionParams.setConnectionTimeout(params, 20000);
    /* 请求超时 */
    HttpConnectionParams.setSoTimeout(params, 40000);
    SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory
    .getSocketFactory()));
    PoolingClientConnectionManager cm = new PoolingClientConnectionManager(
    schemeRegistry);
    cm.setMaxTotal(10);
    HttpHost localhost = new HttpHost("locahost", 80);  

    cm.setMaxPerRoute(new HttpRoute(localhost), 50);
    cm.setDefaultMaxPerRoute(20);

    final HttpClient httpClient = new DefaultHttpClient(cm, params);