public class HttpClientFactory {
      private static  DefaultHttpClient httpClient;
          public static  DefaultHttpClient getHttpClient(){
           if(httpClient==null){
           HttpParams params = new BasicHttpParams();
           
               // 增加最大连接到200               ConnManagerParams.setMaxTotalConnections(params, 200);               // 增加每个路由的默认最大连接到20               ConnPerRouteBean connPerRoute = new ConnPerRouteBean(20);               // 对localhost:80增加最大连接到50               HttpHost localhost = new HttpHost("locahost", 80);               connPerRoute.setMaxForRoute(new HttpRoute(localhost), 100);               ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute);               SchemeRegistry schemeRegistry = new SchemeRegistry();               schemeRegistry.register(               new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));               schemeRegistry.register(               new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));               ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);              
                
                return new DefaultHttpClient(cm, params);
           }else{
           return httpClient;
           }
          
          }
}
如果在多线程中这样调用如下这个类的action()方法,就不会有并发问题package http;import https.HttpClientFactory;import java.io.IOException;import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;public class HttpConnect { private static HttpClient client = HttpClientFactory.getHttpClient(); public static HttpResponse action(String url) {
try {
return client.execute(new HttpPost(url));
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}}
但是如果稍加改动,就会产生并发,数据丢失。改动如下
public class HttpConnect { //private static HttpClient client = HttpClientFactory.getHttpClient(); public static HttpResponse action(String url) {
try {
return  HttpClientFactory.getHttpClient().execute(new HttpPost(url));
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}}这两种写法应该没区别阿,怎么第二种会产生并发问题呢,真是百思不得其解啊。classurl

解决方案 »

  1.   

    我的java方面的多线程经验不多,不过可以很确定的是多线程是占资源的,同时读写一块资源如果不加锁,肯定会出问题的。资源争夺么。你可以检查一下,是不是多线程的结果是正确的。我感觉问题出在HttpClientFactory中,第一种不会出问题是因为client是静态的。保存了上次的结果。
      

  2.   

    我的电脑多的就是资源,我要的只是速度。
    难度HttpClientFactory.getHttpClient()得到的不是静态的?
      

  3.   


    不是系统资源,是多线程同时访问的那块资源。这是多线程最忌讳的问题。也就是说,多个线程同时访问了一个资源,造成了资源的争夺。每一个写成static的变量,都有可能成为出错的地方。我们公司有多线程方面的专家,经常这样教导我。抱歉我对JAVA多线程不熟,只能给你一个提示,没法帮你解决问题。
      

  4.   

    我刚刚想明白了,是在 getHttpClient()在这个方法里面并发了,产生了多个HttpClient。真不理解Apache是怎么设计的,必须很多线程访问同一个HttpCient才不会并发,访问一个以上的HttpClient就会并发。你是做移动的阿,我开年的时候找android 工作没找到,就来搞java了,在公司也没什么事情,随便研究下东西。