Apache的commons-pool池创建多线程使用WebClient

原创 2016年08月28日 14:11:10
package test;

import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.apache.log4j.Logger;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
//http://blog.csdn.net/m13321169565/article/details/8081410
public class PooledClientFactory{
    private static Logger log = Logger.getLogger(PooledClientFactory.class);
    private final static PooledClientFactory instance =new PooledClientFactory();
    //另外一种方案或许更为合适——对象池化技术。
    //基于Apache的commons-pool池
    private final GenericObjectPool clientPool =new GenericObjectPool();
    public static PooledClientFactory getInstance() {
        return instance;
    }
    
    public PooledClientFactory(){
        
        //实现对象池的对象创建工厂接口
        clientPool.setFactory(new PoolableObjectFactory() {
             // 创建对象实例,用于填充对象池。同时可以分配这个对象适用的资源。  
            @Override
            public Object makeObject() throws Exception  {
                log.info("为线程 [ " + Thread.currentThread().getName()+ 
                        " ] 创建新的WebClient实例!");
                
                 WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17);  
                    
                   //设置webClient的相关参数  
                  webClient.getCookieManager().setCookiesEnabled(true);// 开启cookie管理
                    webClient.getOptions().setJavaScriptEnabled(true);// 开启js解析
                    webClient.getOptions().setCssEnabled(false);
                    // 当出现Http error时,程序不抛异常继续执行
                    webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
                    // 防止js语法错误抛出异常
                    webClient.getOptions().setThrowExceptionOnScriptError(false); // js运行错误时,是否抛出异常
                    webClient.getOptions().setTimeout(10000);
                    // 默认是false, 设置为true的话不让你的浏览行为被记录
                    webClient.getOptions().setDoNotTrackEnabled(false);
                    // 设置Ajax异步处理控制器即启用Ajax支持
                    webClient
                            .setAjaxController(new NicelyResynchronizingAjaxController());
                    return webClient;
            }
            
             // 销毁对象,销毁对象池时被调用,连接池调用invalidateObject(obj)时被调用 
            @Override
            public void destroyObject(Object arg0) throws Exception {
                  log.info("销毁对象:" + arg0);  
                WebClient client = (WebClient) arg0;
                client.closeAllWindows();
                client = null;
            }
            
            //  查询对象有效性,需要对象池设置setTestOnBorrow(true),无效对象将被destroy
            @Override
            public boolean validateObject(Object arg0) {
                 log.info("检查对象有效性:" + arg0);  
                return true;
            }

              // 激活一个对象,从对象池获取对象时被调用  

            @Override
            public void activateObject(Object arg0) throws Exception {
                 log.info("激活对象:" + arg0);  
            }
            
             // 挂起(钝化)一个对象,将对象还给对象池时被调用
            @Override
            public void passivateObject(Object arg0) throws Exception {
                
                 log.info("挂起对象:" + arg0);  
            }

        });
        
        clientPool.setTestOnBorrow(true);
        //借出对象达到最大值的最大等待时间,5s等待时间过后抛出异常
        //clientPool.setMaxWait(5000);
        //设置最大可借出数量,默认为8
        clientPool.setMaxActive(10);
    }

    
    
    
    
    
    
    public WebClient getClient()  {
        try {
            return (WebClient)this.clientPool.borrowObject();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        
    }
    
    public void returnClient(WebClient client) {
        try {
            this.clientPool.returnObject(client);
        } catch (Exception e) {
            e.printStackTrace();
        }
        }

    
      //测试对象池
      public static void main(String[] args) {
          try {
              //CursorableLinkedList
            //得到池中空闲的对象数量,如果不可用返回负数
                log.info(PooledClientFactory.getInstance().clientPool.getNumIdle());
                
       //取出对象1
        Object obj1=    PooledClientFactory.getInstance().getClient();
        //取出对象2
        Object obj2=    PooledClientFactory.getInstance().getClient();
        //取出对象3
                Object obj3=    PooledClientFactory.getInstance().getClient();    
            //如果对象借出达到最大数量MaxActive,程序会一直等待有可用的对象(归还的),也可以通过DEFAULT_MAX_WAIT设置等待时间,默认为-1一直等待
                PooledClientFactory.getInstance().getClient();    
                PooledClientFactory.getInstance().getClient();    
                PooledClientFactory.getInstance().getClient();    
                PooledClientFactory.getInstance().getClient();    
                PooledClientFactory.getInstance().getClient();    
                PooledClientFactory.getInstance().getClient();    
            //归还对象1
                
            
        PooledClientFactory.getInstance().returnClient((WebClient) obj1);
        
        //得到池中空闲的对象数量
        log.info(PooledClientFactory.getInstance().clientPool.getNumIdle());
         //    返回从池中借出的对象数量
        log.info(PooledClientFactory.getInstance().clientPool.getNumActive());
        
        //最大可借出数量
        log.info(PooledClientFactory.getInstance().clientPool.getMaxActive());
        //最大空闲数量
        log.info(PooledClientFactory.getInstance().clientPool.getMaxIdle());
        //最小空闲数量
        log.info(PooledClientFactory.getInstance().clientPool.getMinIdle());
        
        
        PooledClientFactory.getInstance().clientPool.clear();
        PooledClientFactory.getInstance().clientPool.close();
        
        //使用工厂创建一个对象
        PooledClientFactory.getInstance().clientPool.getMaxActive();
        } catch (Exception e) {
            
            e.printStackTrace();
        }
        
    }
}


本文出自 “点滴积累” 博客,请务必保留此出处http://tianxingzhe.blog.51cto.com/3390077/1792545

版权声明:本文为博主原创文章,未经博主允许不得转载。

为什么WebClient在多线程中的操作会影响到UI线程(标题党)

最明显的问题就是UI线程会卡但不会卡死,但绝对没有操作UI线程 用DownloadString几乎不卡,用UploadData很容易卡 如果UploadData操作所使用的时间短的话那也不是多卡 但问...
  • z1101385391
  • z1101385391
  • 2013年12月20日 13:46
  • 1441

Apache Commons pool 简介和pool连接池代码

在实际中工作,我们经常遇到需要连接池的地方,特别是数据库连接池。 我们为什么需要池呢?因为这些资源的创建,都很消耗资源。因此,我们使用一个对象池,里面预先创建了一些资源对象。当我们需要时,从池中取出...
  • ffm83
  • ffm83
  • 2014年12月20日 16:40
  • 2113

Apache Commons-pool2简记

Apache旗下的对象池框架common-pool2 官方网址:https://commons.apache.org/proper/commons-pool/配置详解:maxTotal 允许创建资...
  • caiwenfeng_for_23
  • caiwenfeng_for_23
  • 2017年04月09日 12:38
  • 955

解决htmlunit的webclient对象在多线程环境下的共享问题

HtmlUnit在多线程环境下怎么使用才能避免网页抓取失败的问题。下面浅谈该问题的解决办法。 导致这个问题的原因其实蛮简单,举个例子来说,A线程正在使用一个WebClient对象抓取网页,在整个抓取...
  • andybbc
  • andybbc
  • 2016年01月28日 13:51
  • 1968

三分钟让你学会如何使用 apache-common-pool2 创建自己的资源池

apache-common-pool2 如何使用
  • liang_love_java
  • liang_love_java
  • 2016年01月13日 15:39
  • 6584

WebClient的详细用法

提供向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法。不能继承此类。[Visual Basic]NotInheritable Public Class WebClientInh...
  • bluemoon213
  • bluemoon213
  • 2005年12月21日 17:20
  • 20113

commons-pool2和commons-pool对象池使用

概念  对象池(ObjectPool): 掌管对象的生命周期,获取,激活,验证,钝化,销毁等  池对象(PooledObject): 被创建在池中的对象,自己可以有一些附加信息  池对象工厂(Pool...
  • xlxxcc
  • xlxxcc
  • 2016年09月01日 20:08
  • 6503

Apache内存池使用过程的分析

毫无疑问,内存池使用的总的流程是:首先创建一个内存池,在创建的过程中指定它的父内存池,并需要将其挂接到对应的内存池树层次结构上;其次,使用内存池,刚开始使用时内存池中除了本身结点的一点空间外,没有其他...
  • u014398664
  • u014398664
  • 2015年11月29日 14:15
  • 616

apache commons-pool的配置参数

转自:http://www.thinksaas.cn/group/topic/96620/ apache commons-pool的配置参数 write by yinmin...
  • wjacketcn
  • wjacketcn
  • 2016年03月02日 13:34
  • 1173

WebClient 多线程并发限制 下载限制

.net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 windows xp , windows  7 下默认是2,在服务器操作...
  • woodenmen
  • woodenmen
  • 2014年08月22日 13:24
  • 1718
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Apache的commons-pool池创建多线程使用WebClient
举报原因:
原因补充:

(最多只允许输入30个字)