- 浏览: 7331577 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (1546)
- 企业中间件 (236)
- 企业应用面临的问题 (236)
- 小布Oracle学习笔记汇总 (36)
- Spring 开发应用 (54)
- IBatis开发应用 (16)
- Oracle基础学习 (23)
- struts2.0 (41)
- JVM&ClassLoader&GC (16)
- JQuery的开发应用 (17)
- WebService的开发应用 (21)
- Java&Socket (44)
- 开源组件的应用 (254)
- 常用Javascript的开发应用 (28)
- J2EE开发技术指南 (163)
- EJB3开发应用 (11)
- GIS&Mobile&MAP (36)
- SWT-GEF-RCP (52)
- 算法&数据结构 (6)
- Apache开源组件研究 (62)
- Hibernate 学习应用 (57)
- java并发编程 (59)
- MySQL&Mongodb&MS/SQL (15)
- Oracle数据库实验室 (55)
- 搜索引擎的开发应用 (34)
- 软件工程师笔试经典 (14)
- 其他杂项 (10)
- AndroidPn& MQTT&C2DM&推技术 (29)
- ActiveMQ学习和研究 (38)
- Google技术应用开发和API分析 (11)
- flex的学习总结 (59)
- 项目中一点总结 (20)
- java疑惑 java面向对象编程 (28)
- Android 开发学习 (133)
- linux和UNIX的总结 (37)
- Titanium学习总结 (20)
- JQueryMobile学习总结 (34)
- Phonegap学习总结 (32)
- HTML5学习总结 (41)
- JeeCMS研究和理解分析 (9)
最新评论
-
lgh1992314:
[u][i][b][flash=200,200][url][i ...
看看mybatis 源代码 -
尼古拉斯.fwp:
图片根本就不出来好吧。。。。。。
Android文件图片上传的详细讲解(一)HTTP multipart/form-data 上传报文格式实现手机端上传 -
ln94223:
第一个应该用排它网关吧 怎么是并行网关, 并行网关是所有exe ...
工作流Activiti的学习总结(八)Activiti自动执行的应用 -
ZY199266:
获取不到任何消息信息,请问这是什么原因呢?
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息 -
xiaoyao霄:
DestinationSourceMonitor 报错 应该导 ...
ActiveMQ 通过JMX监控Connection,Queue,Topic的信息
1 对象池技术的原理:
对象池技术在服务器开发上应用广泛。在各种对象池的实现中,尤其以数据库的连接池最为明显,可以说是每个服务器必须实现的部分。本文是个人学习对象池的一个记录,以Apache的commons-pool实现为研究对象。在第二部分中,本人将继续研究Apache的common-dbcp,这是对象池技术在JDBC上的一个应用范例。ObjectPool维护一个列表,其中存放所有已经生成的对象。同时导出几个方法,如 borrowObject,returnObject,addObject等等。当用户调用borrowObject时,ObjectPool查看当前列表中的空闲对象的数目,如果有空闲的对象,则初始化该对象后返回给用户,否则创建一个对象,返回给用户使用。同理,当用户调用returnObject 时,ObjectPool查看当前队列中的空闲对象数目,如果数目小于DEFAULT_MAX_SLEEPING,则将改对象的状态清空,然后放到队列中,作为备用对象;否则直接销毁该对象。
对象池中还涉及到一些高级的技术, 比如过期销毁, 被破坏时销毁, 对象数超过池大小销毁, 对象池中没有可用空闲对象时等待等等.
apache的common-pool工具库是对池化技术原理的一种具体实现. 在阐述原理之前, 这里先理解几个概念:
对象池(ObjectPool接口): 可以把它认为是一种容器, 它是用来装池对象的, 并且包含了用来创建池对象的工厂对象
池对象:就是要放到池容器中的对象, 理论上可以是任何对象.
对象池工厂(ObjectPoolFactory接口):用来创建对象池的工厂, 这个没什么好说的.
池对象工厂(PoolableObjectFactory 接口):用来创建池对象, 将不用的池对象进行钝化(passivateObject), 对要使用的池对象进行激活(activeObject), 对池对象进行验证(validateObject), 对有问题的池对象进行销毁(destroyObject)等工作
池对象:就是要放到池容器中的对象, 理论上可以是任何对象.
对象池工厂(ObjectPoolFactory接口):用来创建对象池的工厂, 这个没什么好说的.
池对象工厂(PoolableObjectFactory 接口):用来创建池对象, 将不用的池对象进行钝化(passivateObject), 对要使用的池对象进行激活(activeObject), 对池对象进行验证(validateObject), 对有问题的池对象进行销毁(destroyObject)等工作
对象池中封装了创建, 获取, 归还, 销毁池对象的职责, 当然这些工作都是通过池对象工厂来实施的, 容器内部还有一个或多个用来盛池对象的容器.对象池会对容器大小, 存放时间, 访问等待时间, 空闲时间等等进行一些控制, 因为可以根据需要来调整这些设置.
当需要拿一个池对象的时候, 就从容器中取出一个, 如果容器中没有的话, 而且又没有达到容器的最大限制, 那么就调用池对象工厂, 新建一个池对象, 并调用工厂的激活方法, 对创建的对象进行激活, 验证等一系列操作. 如果已经达到池容器的最大值, 而对象池中又经没有空闲的对象, 那么将会继续等待, 直到有新的空闲的对象被丢进来, 当然这个等待也是有限度的, 如果超出了这个限度, 对象池就会抛出异常.
“出来混, 总是要还的”, 池对象也是如此, 当将用完的池对象归还到对象池中的时候, 对象池会调用池对象工厂对该池对象进行验证, 如果验证不通过则被认为是有问题的对象, 将会被销毁, 同样如果容器已经满了, 这个归还池对象将变的”无家可归”, 也会被销毁, 如果不属于上面两种情况, 对象池就会调用工厂对象将其钝化并放入容器中. 在整个过程中, 激活, 检查, 钝化处理都不是必须的, 因此我们在实PoolableObjectFactory接口的时候, 一般不作处理, 给空实现即可, 所以诞生了BasePoolableObjectFactory.
当然你也可以将要已有的对象创建好, 然后通过addObject放到对象池中去, 以备后用.
为了确保对对象池的访问都是线程安全的, 所有对容器的操作都必须放在synchronized中.
这种备用的观念正是对象池的理论基础,可以很大程度上减少对象生成和销毁的次数。对于那些初始化过程很慢的对象来说,减少对象构造和销毁的次数就等于大幅度提高了整体效率。特别是对于数据库连接这样的对象,由于进行JNDI搜索的效率极为低下,应用对象池技术是理所当然的。需要注意的是,对象池技术并不是对任何对象都适用。因为对象池本身的操作要耗费一些资源,对于一些小对象来说,使用对象池可能取得相反的效果。IBM DeveloperWorks上有一篇论文,指出简单对象如Point,Size等,使用对象池技术并不能带来性能的改善;而复杂对象如 JPanel,JFrame等,使用对象池后能带来稍微的性能优势;最最适合对象池技术的是一些耗时操作,如JDBC连接,线程等。
2 研究 Apache common pool
对象池结构:
在 apache的common-pool工具库中有5种对象池:GenericObjectPool和 GenericKeyedObjectPool, SoftReferenceObjectPool, StackObjectPool, StackKeyedObjectPool.
五种对象池可分为两类, 一类是无key的(有key的类图相似):
五种对象池可分为两类, 一类是无key的(有key的类图相似):
前面两种用CursorableLinkedList来做容器
SoftReferenceObjectPool用ArrayList做容器, 一次性创建所有池化对象, 并对容器中的对象进行了软引用(SoftReference)处理, 从而保证在内存充足的时候池对象不会轻易被jvm垃圾回收, 从而具有很强的缓存能力.
最后两种用Stack做容器. 不带key的对象池是对前面池技术原理的一种简单实现, 带key的相对复杂一些, 它会将池对象按照key来进行分类, 具有相同的key被划分到一组类别中, 因此有多少个key, 就会有多少个容器. 之所以需要带key的这种对象池, 是因为普通的对象池通过makeObject()方法创建的对象基本上都是一模一样的, 因为没法传递参数来对池对象进行定制.
因此四种池对象的区别主要体现在内部的容器的区别, Stack遵循”后进先出”的原则并能保证线程安全, CursorableLinkedList是一个内部用游标(cursor)来定位当前元素的双向链表, 是非线程安全的, 但是能满足对容器的并发修改.ArrayList是非线程安全的, 便利方便的容器.
使用对象池的一般步骤:创建一个池对象工厂, 将该工厂注入到对象池中, 当要取池对象, 调用borrowObject, 当要归还池对象时, 调用returnObject, 销毁池对象调用clear(), 如果要连池对象工厂也一起销毁, 则调用close().
下面是一些时序图:
common-dbcp的结构下面是一些时序图:
apache的连接池工具库common-dbcp是common-pool在数据库访问方面的一个具体应用.当对common-pool熟悉之后, 对common-dbcp就很好理解了. 它通过对已有的Connection, Statment对象包装成池对象PoolableConnection, PoolablePreparedStatement. 然后在这些池化的对象中, 持有一个对对象池的引用, 在关闭的时候, 不进行真正的关闭处理, 而是通过调用:
1. _pool.returnObject(this);
或:
1. _pool.returnObject(_key,this);
这样一句, 将连接对象放回连接池中.
而对应的对象池前者采用的是ObjectPool, 后者是KeyedObjectPool, 因为一个数据库只对应一个连接, 而执行操作的Statement却根据Sql的不同会分很多种. 因此需要根据sql语句的不同多次进行缓存
在对连接池的管理上, common-dbcp主要采用两种对象:
一个是PoolingDriver, 另一个是PoolingDataSource, 二者的区别是PoolingDriver是一个更底层的操作类, 它持有一个连接池映射列表, 一般针对在一个jvm中要连接多个数据库, 而后者相对简单一些. 内部只能持有一个连接池, 即一个数据源对应一个连接池.
下面是common-dbcp的结构关系:
下面是参考了common-dbcp的例子之后写的一个从连接池中获取连接的工具类
1. /**
2. * 创建连接
3. *
4. * @since 2009-1-22 下午02:58:35
5. */
6. public class ConnectionUtils {
7. // 一些common-dbcp内部定义的protocol
8. private static final String POOL_DRIVER_KEY = "jdbc:apache:commons:dbcp:";
9. private static final String POLLING_DRIVER = "org.apache.commons.dbcp.PoolingDriver";
10.
11. /**
12. * 取得池化驱动器
13. *
14. * @return
15. * @throws ClassNotFoundException
16. * @throws SQLException
17. */
18. private static PoolingDriver getPoolDriver() throws ClassNotFoundException,
19. SQLException {
20. Class.forName(POLLING_DRIVER);
21. return (PoolingDriver) DriverManager.getDriver(POOL_DRIVER_KEY);
22. }
23.
24. /**
25. * 销毁所有连接
26. *
27. * @throws Exception
28. */
29. public static void destory() throws Exception {
30. PoolingDriver driver = getPoolDriver();
31. String[] names = driver.getPoolNames();
32. for (String name : names) {
33. driver.getConnectionPool(name).close();
34. }
35. }
36.
37. /**
38. * 从连接池中获取数据库连接
39. */
40. public static Connection getConnection(TableMetaData table)
41. throws Exception {
42. String key = table.getConnectionKey();
43.
44. PoolingDriver driver = getPoolDriver();
45.
46. ObjectPool pool = null;
47. // 这里找不到连接池会抛异常, 需要catch一下
48. try {
49. pool = driver.getConnectionPool(key);
50. } catch (Exception e) {
51. }
52.
53. if (pool == null) {
54. // 根据数据库类型构建连接工厂
55. ConnectionFactory connectionFactory = null;
56. if (table.getDbAddr() != null
57. && TableMetaData.DB_TYPE_MYSQL == table.getDbType()) {
58. Class.forName(TableMetaData.MYSQL_DRIVER);
59. connectionFactory = new DriverManagerConnectionFactory(table
60. .getDBUrl(), null);
61. } else {
62. Class.forName(TableMetaData.ORACLE_DRIVER);
63. connectionFactory = new DriverManagerConnectionFactory(table
64. .getDBUrl(), table.getDbuser(), table.getDbpass());
65. }
66.
67. // 构造连接池
68. ObjectPool connectionPool = new GenericObjectPool(null);
69. new PoolableConnectionFactory(connectionFactory, connectionPool,
70. null, null, false, true);
71.
72. // 将连接池注册到driver中
73. driver.registerPool(key, connectionPool);
74. }
75.
76. // 从连接池中拿一个连接
77. return DriverManager.getConnection(POOL_DRIVER_KEY + key);
78. }
79.
80. }
虽然对象池技术在实际开发过程中用的不是很多, 但是理解之后对我们写程序还是有莫大的好处的, 至少我是这样的
3 用法:
dbcp([url]http://jakarta.apache.org/commons/dbcp/[/url])这个apache的开源的数据库连接池。结果发现dbcp依赖Apache common pool([url]http://jakarta.apache.org/commons/pool/[/url])
关于对象池更多具体用法:
[url]http://www.ibm.com/developerworks/cn/java/l-common-pool/index.html#4[/url]
本文出自 51CTO.COM技术博客评论
2 楼
longgangbai
2009-09-23
转载别人的文章,人家说"可以认为"是一种容器,但并没有说"是容器",所以并不是所谓的错误!可能类似比喻的说法吧,本人一家之言!^_^
1 楼
蔡华江
2009-09-18
引用
对象池(ObjectPool接口): 可以把它认为是一种容器, 它是用来装池对象的, 并且包含了用来创建池对象的工厂对象
池对象:就是要放到池容器中的对象, 理论上可以是任何对象.
对象池工厂(ObjectPoolFactory接口):用来创建对象池的工厂, 这个没什么好说的.
池对象工厂(PoolableObjectFactory 接口):用来创建池对象, 将不用的池对象进行钝化(passivateObject), 对要使用的池
池对象:就是要放到池容器中的对象, 理论上可以是任何对象.
对象池工厂(ObjectPoolFactory接口):用来创建对象池的工厂, 这个没什么好说的.
池对象工厂(PoolableObjectFactory 接口):用来创建池对象, 将不用的池对象进行钝化(passivateObject), 对要使用的池
雷到人了
要好生排版下!
发表评论
-
[转]Jython初探
2014-01-07 11:19 2407转载自: ... -
ireport导出各种格式(pdf,excel,word,html,print)
2013-05-02 16:59 10046import java.io.IOException; ... -
【转】使用Atomikos Transactions Essentials实现多数据源JTA分布式事务
2013-04-03 12:11 6793Atomikos数据源配置方法有三种 Atomikos数 ... -
【转】Apache Thrift入门1-架构&介绍
2013-04-02 13:26 2033Thrift 是什么? Thrift ... -
【转】Thrift入门及Java实例演示
2013-04-02 12:47 2577目录: 概述 下载配置 基本概念 数据类型 ... -
【转】Thrift入门试用
2013-04-02 12:39 2176在新的项目中公司在平台内部系统间使用Thrift通讯,都没 ... -
【转】thrift的安装
2013-04-02 12:38 2090一、ubuntu下thrift的安装 1.下载源代码 ... -
GIS的学习(二十五)geoserver wms中的各种操作API详细讲解和使用
2012-09-10 17:42 9699官方geoserver中WMS服务中几种操作的API的详细说明 ... -
POI3.8组件研究(九)----让POI架起Java与Office之间的桥梁
2012-06-17 14:37 4318本文将阐述如何用POI来读取/写入完整的Excel文 ... -
POI3.8组件研究(八)--基于SXSSF (Streaming Usermodel API)的写文件
2012-06-17 14:17 14431在POI3.8中SXSSF仅仅支持excel2 ... -
POI3.8组件研究(七)--基于XSSF and SAX (Event API)事件的解析
2012-06-17 14:00 5361针对Event API事件解析仅仅支持excel97~ ... -
POI3.8组件研究(六)---struts2.0 视图层文件页面点击导出
2012-06-17 13:23 2415在struts2.0中点击导出按钮将信息导出为exce ... -
POI3.8组件研究(五)---excel文件内容抽取为文本
2012-06-15 09:15 4363在一个搜索引擎的使用中需要将各种文件转化为文本 ... -
POI3.8组件研究(四)--Event API (HSSF Only)事件的解析
2012-06-14 17:37 9058通过eventusermodel读取文件 ... -
POI3.8组件研究(二)---基于User API (HSSF and XSSF)解析Excel2003和2007文件
2012-06-14 09:46 3214在解析生成excel2003和 ... -
POI3.8组件研究(一)---基于User API (HSSF and XSSF)解析Excel2003和2007文件
2012-06-14 09:29 5351在以前的Excel解析时候,我们通常需要编写Ex ... -
EasyPOI的使用
2012-02-12 17:06 5307EasyPOI 的目的是封装了poi的写excel的API。 ... -
Commons-net FTPClient上传下载的封装
2011-08-25 08:30 11509在项目中使用到FTP功能,于是采用类似Spri ... -
Java将第三方jar文件打包到一个jar中的插件(fatjar)
2011-08-19 22:17 4333<!-- google_ad_section_star ... -
Apache的Commons-configuration自动加载特性
2011-07-24 19:04 4072在一些项目可能配置文件经常变化,配置文件的类型可能 ...
相关推荐
### Java对象池技术的原理及其实现 #### 摘要 本文深入探讨了Java对象池技术的基本原理及其实现方式,旨在帮助读者理解如何利用对象池优化Java应用程序的性能。通过对对象池技术核心概念——缓存与共享的阐述,本文...
### Java对象池技术的原理 在Java开发领域中,对象池技术是一种常用的设计模式,用于管理可重用的对象集合,从而提高系统性能并减少资源消耗。本文将详细探讨Java对象池技术的基本原理及其具体实现方式。 #### ...
对象池技术是在游戏中管理瞬时对象的有效方法之一,特别是在需要频繁创建和销毁大量相似游戏对象(例如子弹、粒子效果、爆炸动画等)的情况下。通过预先加载一定数量的对象并在需要时激活它们,而不是不断地创建和...
对象池技术---免费
"基于OCI和对象池技术的跨平台Oracle数据源管理中间件的实现" 本文主要讨论基于OCI和对象池技术的跨平台Oracle数据源管理中间件的实现。该中间件使用C++语言实现,提供了统一的数据访问接口,支持多线程数据访问,...
对象池是一种在软件设计中常见的优化技术,主要目的是提高程序性能和减少系统资源的消耗。在Java编程中,对象池通常用于管理那些创建和销毁成本较高的对象,通过...理解并熟练应用对象池技术对于提升系统性能至关重要。
Unity对象池是一种优化游戏性能的技术,它通过预先创建并存储一系列可重用的游戏对象,避免了频繁的..."unity对象池的案例Demo"应该为我们提供了实践这些概念的实际代码和步骤,帮助我们更好地理解和应用对象池技术。
5. **代码注释**:为了帮助理解,Demo案例中的代码会有详细的注释,解释每个步骤的作用和实现方式,帮助开发者更好地理解和应用对象池技术。 通过学习这个Demo,开发者可以了解到如何在实际项目中应用对象池,如何...
### 对象池技术详解 #### 一、对象池的基本概念 在软件开发中,特别是针对高性能、高并发的应用场景,对象池技术是一种非常实用的设计模式。它主要用于避免频繁创建和销毁对象所带来的性能开销,特别是在对象创建...
Apache对象池技术是一种高效利用资源的策略,它通过预先创建并维护一组可重用对象来减少频繁创建和销毁对象带来的开销。在Java环境中,Apache Commons Pool库是实现对象池的常见工具,它提供了多种对象池实现,适用...
通过理解并应用对象池技术,开发者能够更有效地管理资源,减少内存压力,提高游戏运行效率。在"StudyDuiXiangChi"这个项目中,你可以进一步研究和实践这些概念,以创建自己的优化工具和解决方案。
游戏开发中的对象池技术是一种优化资源管理的策略,它通过预先创建并缓存一组对象,以避免频繁地创建和销毁对象带来的性能开销。在这个"游戏对象池例子(兼容智能指针、工厂类)"中,我们将探讨如何利用C++实现这种...
为了解决这一问题,程序员通常会采用对象池技术,Go语言也不例外。"Go Commons Pool"就是这样一个专门用于Golang的通用对象池库,它旨在提高程序运行效率,降低系统资源的频繁分配与回收带来的开销。 对象池的基本...
本项目是一个基于Java的对象池管理系统,旨在通过对象池技术减少频繁创建和销毁对象所带来的开销,从而提高系统性能和资源利用率。对象池技术允许在需要时从池中获取已存在的对象,而不是每次都创建新对象,使用完毕...
Pool Spawner Pro 通过对象池技术,避免了 Unity 内置的 Instantiate () 和 Destroy () 函数所带来的性能问题,因为对象池重用对象而不是持续创建和销毁新对象。 该工具包包含三种系统: 动态生成(Dynamic Spawn)...
Egret对象池技术在游戏开发中的应用是一个重要的性能优化策略,主要针对频繁创建和销毁的对象,例如在飞机游戏中常见的子弹。对象池通过预先创建一组对象并存储在池中,当需要新对象时,不再直接新建,而是从池中...
Unity3D对象池插件是游戏开发中一种高效管理资源的技术实现,主要目的是优化游戏性能,减少内存分配和...通过合理利用对象池技术,开发者可以创造出更加流畅、低延迟的游戏体验,特别是在处理大量动态对象的场景中。
对象池是一种资源管理技术,用于预先创建一组对象并存储在一个“池”中,当需要对象时,可以从池中获取,而不是每次需要时都创建新的对象。这样可以显著减少对象的创建和销毁开销,尤其是在创建对象成本高或者系统...
对象池技术就是一种常用的优化手段,特别是在ActionScript 3(AS3)这种面向对象的编程语言中。本文将深入探讨“对象池优化”,以及如何通过工厂方法改进对象管理,以提高程序效率。 对象池是一种设计模式,它预先...