HttpClient访问的多线程问题

在发出HTTP请求前先创建一个HttpClient对象,而在实际的项目中,很可能多处需要进行HTTP通信,这时候不需要新建一个HttpClient,因为之前已经建好啦。对于整个应用一个

HttpClient就够了。例如下面代码:

public class CustomerHttpClient{
   private static HttpClient customerHttpClient;
   private CustomerHttpClient{
   }
   
   public static HttpClient getHttpClient{
     if(customerHttpClient==null){
       customerHttpClient=new DefaultHttpClie    nt;
}
return customerHttpClient;
}
}

但是用HttpClient管理所有的HttpClient一旦出现并发请求,那么一定会出现多线程问题。不过幸运的是HttpClient提供了创建线程安全的Api能帮助我们创建线程安全的Httpclient

如下面的代码:

import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnManagerParams;
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.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
/**
 * 多请求时,解决多线程问题。
 * @author 超超boy
 *
 */
public class CustomerHttpClient
{
	private static final String CHARSET=HTTP.UTF_8;
    private static HttpClient httpClient;
	public CustomerHttpClient(){
		this.httpClient = this.createHttpClient();
	}
/*synchronized同步的Java语言的关键字,可用来给对象和方法或者代码块加锁,
当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码。
当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。
另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块。*/

	private static synchronized HttpClient createHttpClient(){
	  if(httpClient == null){
	    HttpParams params = new BasicHttpParams();
		//设置一些基本参数、
       HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
       HttpProtocolParams.setContentCharset(params, CHARSET);
       HttpProtocolParams.setUseExpectContinue(params, true);
       
       //超时设置
       /*从连接池中取连接的超时时间*/
       ConnManagerParams.setTimeout(params, 2000);
       /*连接超时*/
       HttpConnectionParams.setConnectionTimeout(params, 2000);
       //请求超时
       HttpConnectionParams.setSoTimeout(params, 4000);
       //设置HttpClient支持Http和Https两种模式
       SchemeRegistry registry = new SchemeRegistry();
       registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));//scheme设计计划  
       registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443)); 
       
     //当实例化DefaultHttpClient时,传入一个由ThreadSafeClientConnManager创建的一个ClientConnectionManager实例,
       //负责管理HttpClient的HTTP连接。多线程时,用ThreadSafeClientConnManager来创建和管理HttpClient
       ClientConnectionManager connMgr = new ThreadSafeClientConnManager(params, registry);  
         
       httpClient = new DefaultHttpClient(connMgr, params);  
	  }
	  return httpClient;
	}
	//关闭连接管理器并释放资源  
    private void shutdownHttpClient() {  
        if (httpClient != null && httpClient.getConnectionManager() != null) {  
            httpClient.getConnectionManager().shutdown();  
        }  
    }  
      
    //对外提供HttpClient实例  
    public HttpClient getHttpClient() {  
        return httpClient;  
    }  	
}

注释很详细,看懂没问题。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值