简介
在以往的一些工作中总接触到一个池的概念。这些池包括有线程池,对象池和连接池等。从池本身的概念来说,它是将一系列的资源事先准备好放在一个地方,等需要的时候直接拿过去用。而用完之后再放回来。和我们平常的需要使用资源再创建的方式相比,这种池的方式节省了创建和销毁资源的这么一个过程。所以说,对于一些比较比较稀缺的资源或者创建和销毁影响系统性能的资源,采用池的方式可以有效的提高整体性能。最近一段时间正好要用到一些数据库连接池等东西,趁这个时机把一些相关的部分好好的学习总结一下。如前面提到的,我们使用到的典型的线程池有jdk里的ExecutorService相关的一系列工具类(在这篇文章里有阐述),而一些典型的数据库连接池有cp03和dbcp。最近用到了dbcp,而它主要是基于commons-pool实现的,所以我们先从commons-pool2开始吧。
整体结构分析
在正式分析commons-pool2的结构开始,我们设想一下,如果我们自己来设计一个object pool的话,我们该怎么来做呢?
首先一个,我们从直接使用的角度来说,肯定需要一个ObjectPool对象,它负责保存我们需要访问的对象,我们把这个对象用完之后就返还给它。更细化一点的考虑的话,我们在使用前需要根据配置事先创建一些对象,后面需要使用的时候直接取就可以了。然后我们需要能够知道pool里面有多少可以用的对象。还有一个就是对象在被使用前是一个类似于初始化的状态,而使用完之后可能是另外的一个状态,既然我们希望对象能够被复用,在返回到pool里的时候可能还需要做一些重置的工作。
除了这些以外,如果我们考虑对象的创建。我们可以将创建对象的职责给pool,这样pool同时既要管理对象的存取和回收又要管对象的创建和状态设置等。这有点像一个图书馆的管理员,他既要管借还书,还要管怎么造纸印书。这样想来,似乎管的职责有点多了。我们也可以将对象的创建单独分离处理作为一个factory来做。
其实,通过前面的这些讨论,我们几乎也能创建一个像模像样的pool。如果结合commons-pool2的详细设计,我们会发现它的设计思路和我们也是基本上一致的。它主要由3个大的部分组成:
ObjectPool:专门实现对象存取和状态管理的池实现。我们直接操作的线程池就是定义在这里。值得注意的一点是这里定义的只是怎么来获取以及释放对象等操作,至于具体对象是怎么创建的,一般都通过独立的一个PooledObjectFactory来操心了。
PooledObject:这是commons-pools里比较有意思的一个类族。是对需要放到池里对象的一个包装类。添加了一些附加的信息,比如说状态信息,创建时间,激活时间,关闭时间等。这些添加的信息方便pool来管理和实现一些特定的操作。
PooledObjectFactory: 如我们前面所讨论的,管理具体对象的状态,比如创建,初始化,验证对象状态和销毁对象。
通过我们的这些讨论,他们这三者就构成了一个object pool的基本框架。他们的关系可以用如下的一个图来描述:
用一句话来概括他们整体的关系就是factory创建需要放入pool的对象,经过PooledObject包装一下就可以上架了。
有一个地方需要注意一下,虽然我们这里将它划分成3个主要的部分,从更精确的细节来看,每一个类族里都有一些不同的实现,这里我们再针对每一类族做一个大体的介绍。
ObjectPool类族
ObjectPool类族包含了以ObjectPool为代表的一系列pool,其中最主要的两类就是ObjectPool和KeyedObjectPool,他们分别针对普通的pool和以名值对映射的pool。和他们相关的整体几个类结构如下图:
从前面的图里头我们可以看到,真正定义的接口就是ObjectPool和KeyedObjectPool,具体的实现里有GenericObjectPool, GenericKeyedObjectPool和SoftReferenceObjectPool。不管是哪一种他们都引用了PooledObject。 这里我们不详细分析具体实现的代码,我们先就前面的设想来验证一下他们的整体思路。既然是ObjectPool,那它就应该管borrowObject, returnObject之类的了。是不是呢?我们先看看ObjectPool这一块的代码:
public interface ObjectPool<T> { T borrowObject() throws Exception, NoSuchElementException, IllegalStateException; void returnObject(T obj) throws Exception; void invalidateObject(T obj) throws Exception; void addObject() throws Exception, IllegalStateException, UnsupportedOperationException; int getNumIdle(); int getNumActive(); void clear() throws Exception, UnsupportedOperationException; void close(); }
这部分的代码很简单直接,主要就是包含了一个pool需要的基本操作功能,比如从pool里取对象的borrowObject,返回对象到pool里的returnObject,还有一些查找里面可用对象数量以及管理pool的方法。这里的clear方法是用来清空里面处于idle状态的对象,而close方法则用来关闭整个pool。他们两者的一个典型差别就是clear之后里面没有可以用的对象了,我们需要再创建一些对象放进去。而close之后则连pool都访问不了了。
与ObjectPool对象的一个是KeyedObjectPool,它的操作方法基本上和ObjectPool一样,唯一的差别是它是基于key来操作的,所以所有相关的borrowObject, returnObject等操作都要提供key参数。
PooledObject类族
如前所述,PooledObject主要是对需要被加入到pool里的对象提供一个包装,方便来查看或者统计一些对象信息,比如某个对象创建的时间,空闲时间以及活跃时间等。下面是PooledObject相关的类关系图:
既然是一个简单的包装,我们就来看看具体需要访问的一些方法。如下是PooledObject里的基本方法定义:
public interface PooledObject<T> extends Comparable<PooledObject<T>> { T getObject(); long getCreateTime(); long getActiveTimeMillis(); long getIdleTimeMillis(); long getLastBorrowTime(); long getLastReturnTime(); long getLastUsedTime(); @Override int compareTo(PooledObject<T> other); @Override boolean equals(Object obj); @Override int hashCode(); @Override String toString(); boolean startEvictionTest(); boolean endEvictionTest(Deque<PooledObject<T>> idleQueue); boolean allocate(); boolean deallocate(); void invalidate(); void setLogAbandoned(boolean logAbandoned); void use(); void printStackTrace(PrintWriter writer); PooledObjectState getState(); void markAbandoned(); void markReturning(); }
这里列出的一大堆方法其实就是标注了各种操作,很多都是PooledObject本身实现加上去的。
ok,有了前面这些管理对象和包装对象的东西,我们再来看看具体制造和销毁对象的部分。
PooledObjectFactory
在commons-pool2里,我们专门抽象出来一个创建和销毁对象的接口,PooledObjectFactory。而具体对象的创建则由用户自定义实现。在本身的源代码里只有一个简单的抽象类BasePooledObjectFactory实现。我们来看看这个接口定义的方法:
public interface PooledObjectFactory<T> { PooledObject<T> makeObject() throws Exception; void destroyObject(PooledObject<T> p) throws Exception; boolean validateObject(PooledObject<T> p); void activateObject(PooledObject<T> p) throws Exception; void passivateObject(PooledObject<T> p) throws Exception; }
makeObject和destroyObject则分别用于创建销毁对象,很简单。而validateObject用于在每次创建对象放入到pool里或者从pool里取对象出来的时候验证是否对象合法。至于activeObject和passivateObject比较有意思。在这里给对象定义了一系列的状态。这里的设计假定所有在pool里可以被立马拿出去用的对象是一个idle状态,在拿到之后要用activateObject方法来激活一下。而对象要返回给pool的时候则要用passivateObject方法将它钝化。
和ObjectPool相对应的,PooledObjectFactory也有一个相应的KeyedPooledObjectFactory,他们的区别也一样,一个是基于key来操作一个不是。
相关推荐
Maven坐标:org.apache.commons:commons-pool2:2.10.0; 标签:apache、commons、pool2、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译...
Apache Commons Pool 2.4.1 是一个广泛使用的对象池库,主要在Java开发中用于高效管理资源。对象池的概念是创建一组预先配置的对象,而不是每次需要时都创建新的对象,这大大减少了对象的创建和销毁开销,提高了应用...
Maven坐标:org.apache.commons:commons-pool2:2.0; 标签:apache、commons、pool2、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,...
Apache Commons Pool2是Java开发中的一个对象池库,主要用于提高对象的重用效率,从而提升系统性能。在本文中,我们将深入探讨这个库的核心概念、设计模式以及如何通过源码学习来理解其工作原理。 首先,Apache ...
Maven坐标:org.apache.commons:commons-pool2:2.10.0; 标签:apache、pool2、commons、jar包、java、中英对照文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化...
对应Maven信息:groupId:org.apache.commons,artifactId:commons-pool2,version:2.5.0 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构...
6. **使用示例**:在实际应用中,用户可以通过以下步骤使用Apache Commons Pool 2: - 引入依赖:在项目中添加`commons-pool2-2.10.0.jar`。 - 创建池配置:例如,`GenericObjectPoolConfig config = new ...
最新版本“commons-pool2-2.8.1.jar”带来了更稳定、更高效的对象池服务。 Apache Commons Pool 2 是其第二代产品,相比第一代,它在API设计、性能和可扩展性方面都有显著提升。2.8.1版本是对该库的一次更新,修复...
Apache Commons Pool 2 是一个广泛使用的对象池库,它的最新版本是 2.5.0。对象池在软件设计中是一种优化资源管理的技术,通过复用已创建的对象,避免频繁的创建和销毁过程,从而提高性能。Apache Commons Pool 2 ...
Maven坐标:org.apache.commons:commons-pool2:2.3; 标签:apache、pool2、commons、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化...
《Apache Commons Pool2详解》 Apache Commons Pool2是一款开源的Java对象池库,它提供了对象池化的服务,能够有效地管理并复用对象,减少频繁创建和销毁对象带来的性能开销。"commons-pool2-2.4.3-bin.zip"是这个...
Maven坐标:org.apache.commons:commons-pool2:2.5.0; 标签:apache、pool2、commons、jar包、java、API文档、中文版; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性...
Maven坐标:org.apache.commons:commons-pool2:2.4.3; 标签:apache、pool2、commons、jar包、java、中文文档; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,...
Maven坐标:org.apache.commons:commons-pool2:2.9.0; 标签:apache、commons、pool2、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,...
Apache Commons Pool 2是该库的最新版本,这里提供的两个压缩文件`commons-pool2-2.11.1-bin.zip`和`commons-pool2-2.11.1-src.zip`分别包含了编译后的二进制库和源代码。`bin.zip`文件通常包含编译好的JAR文件和...
Version 2 of Apache Commons Pool contains a completely re-written pooling implementation compared to the 1.x series. In addition to performance and scalability improvements, version 2 includes robust...
《Apache Commons Pool详解:连接池的关键组件》 Apache Commons Pool是Java编程领域中一个重要的开源库,主要用于对象池化,特别是在数据库连接管理方面扮演着核心角色。标题中的"commons-pool.jar"即为此库的可...
Apache Commons Pool2是一个Java对象池库,用于管理可重用对象。对象池是软件设计中的一个概念,通过池化资源,可以有效地减少创建和销毁对象的开销,提高系统的性能和效率。Apache Commons Pool2是Apache Commons...
Apache Commons Pool2是一个Java对象池库,用于管理可重用对象。对象池是软件设计中的一个概念,它允许程序在需要时重复使用已创建的对象,而不是每次需要时都创建新的对象。这在处理资源密集型对象(如数据库连接或...
Apache Commons Pool2是一个Java对象池库,用于管理资源的复用,特别是数据库连接池。在IT行业中,数据源管理是优化系统性能的关键部分,而Apache Commons Pool2则是实现这一目标的重要工具。本篇将深入探讨这个库的...