`
agapple
  • 浏览: 1583372 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

common-pools源码分析

    博客分类:
  • java
阅读更多

背景

  前段时间研究了下dbcp的一些源码,发现dbcp对common pools依赖比较严重,基本就是基于pool的扩展接口实现的。所以也就顺便看了下pools的源码。

 

总体结构

 

common pools的代码总体结构来说是比较简单的。

 

先上一个类图:


 

 

核心接口类:

  • ObjectPool             对象池
  • ObjectPoolFactory   池的维护工厂
  • PoolableObjectFactory   可池化对象的维护工厂
  • KeyedObjectPool    基于kety的对象池
  • KeyedObjectPoolFactory
  • KeyedPoolableObjectFactory

说明: ObjectPool和KeyedObjectPool基本接口都是一致的,唯一不同的就是KeyedObjectPool是基于key做为键值,其对应的存储结构就是 Map<Object , List<Object>>, 每次根据key定位List<objct>的value后,再进行池化管理。

几个pools的实现类:

1.  GenericObjectPool: 通用的对象池处理类,维护池的大小,空闲链接等等。 针对对象的makeObject,destoryObject等都是委托给PoolableObjectFactory进行处理。

基本参数和dbcp的配置参数一样,可以参考: http://agapple.iteye.com/admin/blogs/772507

关注几个特别的参数:

  • _lifo :  采用的列表管理模式,采用先进先出or后进先出。 默认是先进先出,底层具体的池对象储存是通过CursorableLinkedList。
  • _softMinEvictableIdleTimeMillis : 软性idle空闲管理。默认是-1。 相比于_minEvictableIdleTimeMillis,系统默认优先处理_minEvictableIdleTimeMillis空闲管理机制,除此主要的区别就是处理空闲链接时,soft会考虑当前的池大小是否满足 > minIdle数。
  • _timeBetweenEvictionRunsMillis :  Evict管理线程的运行时间,默认-1。也就是说默认不运行,注意如果要使用idle空闲管理必须设置该值,否则没效果。

2.  StackObjectPool :  基于stack堆栈概念的对象池,对象池的borrow或者return都是符合stack的先进先出弹栈的管理,相比于GenericObjectPool,它只有maxIdle(最大空闲数), maxTotal(最大资源数)管理,暂时还未想到特定的应用场景,因为觉得GenericObjectPool的功能基本可以覆盖StackObjectPool,只要适当的调整参数。

 

3.  SoftReferenceObjectPool :  看名字就应该猜到是基于SoftReference进行对象持有的pool,在内存不足时可以主动的释放pool object对象, 通过ReferenceQueue获取object对象需要被清除的时间点。至于SoftReference可以看下理解 Java 的 GC 与 幽灵引用

 

4.  GenericKeyedObjectPool: 区别于GenericObjectPool,主要是该pool池,针对每个资源都有自己特定的域,就是一个对应的key。每个key下可以有一组object。 maxTotal是针对所有的key下的object之和,而非单个。

 

如何实现自定义的pool

 

首先以dbcp为例,介绍其相关扩展点。

 

 

 

说明:

1. dbcp整个连接池的管理是使用GenericObjectPool

2. dbcp这里通过扩展实现自定义的PoolableObjectFactory , 用于定义如何创建/销毁/校验一个datasource等。

3. 使用的statement cache利用的是GenericKeyedObjectPool,因为statement cache是基于key进行statement管理的,所以比较适合。但目前在使用statement cache会出现一些异常情况,慎用。

4. PoolingConnection实现了statement cache对应池对象的创建/销毁。 同时在datasource的执行close,同时需要清理整个statement cache pool的close动作,避免出现资源泄漏。

 

 

实际demo: 

实现一个memcache client的连接池代码

 

1. 实现一个PoolableObjectFactory接口,提供创建/销毁/校验的方法

 

 
public class MemcachedPoolableSocketFactory implements PoolableObjectFactory {
  .......
  public MemcachedPoolableSocketFactory(String host, int port, int connectedTimeout){
        this.host = host;
        this.port = port;
        this.connectedTimeout = connectedTimeout;
    }

    @Override
    public Object makeObject() throws Exception {
        return new SockIO(host, port, connectedTimeout);
    }

    @Override
    public void destroyObject(Object obj) throws Exception {
        if (obj instanceof SockIO) {
            ((SockIO) obj).close();
        }
    }

    @Override
    public boolean validateObject(Object obj) {
        if (obj instanceof SockIO) {
            SockIO sock = (SockIO) obj;
            try {
                sock.getOut().write("version \r\n".getBytes());
                sock.getOut().flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }
    ......

}
 

2.  创建SocketPool类,用于管理pool

 

public class MemcachedSocketPool {

    private GenericObjectPool sockPool  = null;
    private int               maxActive = 50;
    private int               minIdle   = 1;
    private int               maxIdle   = 50;
    private int               maxWait   = 1000;

    public MemcachedSocketPool(String host, int port){
        sockPool = new GenericObjectPool();
        sockPool.setMaxActive(maxActive);
        sockPool.setMaxIdle(maxIdle);
        sockPool.setMinIdle(minIdle);
        sockPool.setMaxWait(maxWait);
        sockPool.setTestOnBorrow(false);
        sockPool.setTestOnReturn(false);
        sockPool.setTimeBetweenEvictionRunsMillis(10 * 1000);
        sockPool.setNumTestsPerEvictionRun(maxActive + maxIdle);
        sockPool.setMinEvictableIdleTimeMillis(30 * 60 * 1000);
        sockPool.setTestWhileIdle(true);
        sockPool.setFactory(new MemcachedPoolableSocketFactory(host, port, 1000));
    }

    public SockIO createSocket() {
        assert sockPool != null;

        try {
            return (SockIO) sockPool.borrowObject();
        } catch (Exception e) {
        }

        return null;
    }
}

 

 

3. 客户端端使用 

 

MemcachedSocketPool pool = new MemcachedSocketPool("10.20.156.37", 6000);
SockIO sock = pool.createSocket();
sock.write(cmd.getBytes());
sock.flush();

 

 

 

使用common-pools后,实现一个自己的连接池也是相对比较单了

  • 大小: 20.7 KB
  • 大小: 14.5 KB
分享到:
评论
3 楼 housheng33 2012-05-11  
这个点分析得不错!!!

2 楼 agapple 2011-12-03  
zhangyou1010 写道
博主您好,请问文章中的类图是用什么工具画的? 谢谢。


jude,一款java写的,有对应的免费版. 一般linux下用的挺多的
1 楼 zhangyou1010 2011-12-02  
博主您好,请问文章中的类图是用什么工具画的? 谢谢。

相关推荐

    dhcpd-pools:ISC dhcpd租约使用情况分析-开源

    这是dhcpd-pools ISC dhcp共享网络和池范围使用情况的分析。 该命令的目的是计算ISC dhcpd控制的每个IP范围和共享网络池的使用率。 该命令的用户最有可能是具有较大IP空间的ISP和其他组织。 程序用C编写。设计目标是...

    commons-pool2-2.6.1

    commons-pools-2.2.6.1.jar

    relint-ci-pools

    relint-ci-pools更新发布池该池用于更新发布管道,因此可以一次运行多个作业。 当前有4个,并且锁定文件本身包含元数据,该元数据将在cf-deployment-concourse-tasks中使用,以动态地针对正确的环境。 证书本身是...

    vesper-pools

    cd vesper-pools npm install npm run truffle compile 在环境中设置NODE_URL export NODE_URL= 测试 注意:这些测试将按步骤3中的要求派生主网。建议不要一次运行所有测试,而要指定一个文件。 运行单个文件 ...

    swimming-pools:OSM阿尔伯克基的每个游泳池

    OSM游泳池OpenStreet... node index.js 这会将数据下载到名为pools.geojson的文件中,然后将数据压缩到TopoJSON中,以分发给应用程序。 应用程序使用的是TopoJSON,GeoJSON可以作为工件使用。 编译应用npm run build

    php-fpm-pools-single:单个 php-fpm 池 {start,restart,stop}

    用法$ ./pools 站点博客开始$ ./pools 站点博客重新加载$ ./pools 站点博客重启$ ./pools site-blog force-quit $ ./pools 站点博客站

    Distributed-Content-Harvesting-using-Thread-Pools

    包含内容检索和解析的Web内容收集通常是分析任务(例如搜索,广告放置和相关性排名)的先兆。 作为该项目的一部分,我开发了一种分布式内容收集器,该收集器使用线程池来检索和解析内容。 该分布式收割机支持的功能...

    NIM-Pools-Hub-Miner:CPUGPU Nimiq矿工

    NIM池中心矿工 GUI由Albermonte提供,Miner由SushiPool&Mat(tomkha)提供 从发布页面下载最新版本: 运作中的CPU和GPU矿工 构建设置 # install dependencies npm install # serve with hot reload at localhost...

    balancer-pools-analytics:用于计算 Balancer Pools 的 APY 的 Nodejs 脚本

    平衡器池分析(WIP) 用于计算 Balancer Pools 的 APY 的 Nodejs 脚本 安装 npm i # or yarn 用法 node index.js

    Discord-Crypto-Pools-Bot:Discord bot用于列表池

    Node.js Discord Bot 基于: 从本教程

    pie-smart-pools:饼图平衡器智能池控制器

    派智能泳池馅饼智能池是资产管理不可知(目前仅平衡器)d ecentralisedŤraded˚Funds。 它们共享一个通用接口,从而易于集成到其他产品中。 所有智能池都可以完全升级,以便在以后阶段轻松添加功能并优化天然气使用...

    unisave-pools-interface:Y3DScam池接口

    Unisave池接口 该项目是通过引导的。 可用脚本 在项目目录中,可以运行: yarn start 在开发模式下运行应用程序。 打开在浏览器中查看它。 如果您进行编辑,则页面将重新加载。 您还将在控制台中看到任何棉绒错误...

    Scalable-Server-Design-Using-Thread-Pools:这是使用线程池进行可伸缩服务器设计和负载平衡的演示。

    可扩展服务器设计使用线程池 该项目的目的是使用线程池平衡服务器上的负载。 线程创建是一个昂贵的过程,涉及时间和资源,因此,与其为服务器收到的每条消息生成一个线程,不如使用一个线程池执行任务,这是理想的...

    iexec-pools-registry:iExec池注册表,有关如何列出您的工作池的更多信息在下面!

    iExec池注册表为了在上列出您的工作池,您需要使其进入iExec池注册表。 但是放松一下,这很容易: 使用创建和部署iExec WorkerPool,这里是进入此注册表的5个步骤:1. Github Fork这个仓库单击github上的“ Fork”...

    Java-ConnectionPools.rar_连接池

    java数据库连接池打包下载(包括10个连接池)

    osutaiko-pools

    薄樱丽的osu!taiko游泳池资料库 关于 这是一个宣传我自己的地图的地方,同时提供练习来学习给定池中每个层的给定差距。 每个池将在此处完成,并且每月最多更新一次。 泳池 太鼓初学者练习 在参加初学者osu!...

    人工智能-项目实践-多线程-多线程爬虫-抓取淘宝商品详情页URL.zip

    此系统与我之前开发的ip-proxy-pools-regularly结合使用,共抓取了淘宝近3000个页面,从中解析到了近9万的商品详情页URL。 我并没有直接将这些商品详情页中最具价值的数据(商品信息)提取出来,因为这些富有价值的...

    ALV 显示.docx

    TYPE-POOLS:slis. "alv用的的表 DATA lt_fieldcat TYPE slis_t_fieldcat_alv. " 储存fieldcat的内表,(字段清单) DATA wa_fieldcat TYPE slis_fieldcat_alv. " fieldcat 的工作区 DATA ls_layout TYPE slis_layout...

    munin-syncthing:用于同步和同步中继服务器的Munin插件

    munin-plugins-syncthing 插件可监视和。 要求 Munin已经设置并运行 同步已设置并正在运行 同步中继设置和运行 可用的插件 # Syncthing syncthing_transfer # graph the total in/out bits syncthing_cpu # graph...

    pools.unitypackage

    自己写好的对象池,可以拿下来直接用,挺简单的哈,为什么要50个字的描述,能说清楚不久得了,希望改进XXXXXXXXXXXXXXXXXXXX

Global site tag (gtag.js) - Google Analytics