对象池的容器:包含一个指定数量的对象。从池中取出一个对象时,它就不存在池中,直到它被放回。在池中的对象有生命周期:创建,验证,销毁,对象池有助于更好地管理可用资源,防止JVM内部大量临时小对象,频繁触发垃圾回收,造成系统暂停。有许多的使用示例。特别是在应用服务器数据源池,线程池等都是对象池的使用,下面情况适合使用对象池:

  • 同样的对象高频率使用
  • 对象太大消耗很多内存
  • 对象初始化需要时间
  • 对象内涉及IO操作 (Streams, Sockets, DB, etc.)
  • 对象并不是线程安全时。

很多人使用 Apache Commons Pool.它有ObjectPool的接口,ObjectPoolFactory,PoolableObjectFactory和许多的实现。有addObject方法,borrowObject,invalidateObject,返回object添加,删除和返回对象。 PoolableObjectFactory定义对象池的操作行为,并提供各种回调。

但是Apache Commons Pool不是一个轻量开销的对象池,它很多方法采用了不建议使用的旧的Java的关键字synchronized。而Java 5中引入了Executor框架Java并发(多线程)。这里是最好的Executor框架。

package easypool;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; public abstract class ObjectPool<T>
{
private ConcurrentLinkedQueue<T> pool; private ScheduledExecutorService executorService; /**
* Creates the pool.
*
* @param minIdle minimum number of objects residing in the pool
*/
public ObjectPool(final int minIdle) {
// initialize pool
initialize(minIdle);
} /**
* Creates the pool.
*
* @param minIdle minimum number of objects residing in the pool
* @param maxIdle maximum number of objects residing in the pool
* @param validationInterval time in seconds for periodical checking of minIdle / maxIdle conditions in a separate thread.
* When the number of objects is less than minIdle, missing instances will be created.
* When the number of objects is greater than maxIdle, too many instances will be removed.
*/
public ObjectPool(final int minIdle, final int maxIdle, final long validationInterval) {
// initialize pool
initialize(minIdle); // check pool conditions in a separate thread
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(new Runnable()
{
@Override
public void run() {
int size = pool.size();
if (size < minIdle) {
int sizeToBeAdded = minIdle - size;
for (int i = 0; i < sizeToBeAdded; i++) {
pool.add(createObject());
}
} else if (size > maxIdle) {
int sizeToBeRemoved = size - maxIdle;
for (int i = 0; i < sizeToBeRemoved; i++) {
pool.poll();
}
}
}
}, validationInterval, validationInterval, TimeUnit.SECONDS);
} /**
* Gets the next free object from the pool. If the pool doesn't contain any objects,
* a new object will be created and given to the caller of this method back.
*
* @return T borrowed object
*/
public T borrowObject() {
T object;
if ((object = pool.poll()) == null) {
object = createObject();
} return object;
} /**
* Returns object back to the pool.
*
* @param object object to be returned
*/
public void returnObject(T object) {
if (object == null) {
return;
} this.pool.offer(object);
} /**
* Shutdown this pool.
*/
public void shutdown() {
if (executorService != null) {
executorService.shutdown();
}
} /**
* Creates a new object.
*
* @return T new object
*/
protected abstract T createObject(); private void initialize(final int minIdle) {
pool = new ConcurrentLinkedQueue<T>(); for (int i = 0; i < minIdle; i++) {
pool.add(createObject());
}
}
}
package easypool;

public class ExportingProcess {

    private String location;

    private long processNo = 0;

    public ExportingProcess(String location, long processNo) {
this.location = location;
this.processNo = processNo; // doing some time expensive calls / tasks
// ... // for-loop is just for simulation
for (int i = 0; i < Integer.MAX_VALUE; i++) {
} System.out.println("Object with process no. " + processNo + " was created");
} public String getLocation() {
return location;
} public long getProcessNo() {
return processNo;
} @Override
public String toString() {
return "ExportingProcess{" + "processNo=" + processNo + '}';
}
}
package easypool;

public class ExportingTask implements Runnable {

    private ObjectPool<ExportingProcess> pool;

    private int threadNo;

    public ExportingTask(ObjectPool<ExportingProcess> pool, int threadNo) {
this.pool = pool;
this.threadNo = threadNo;
} public void run() {
// get an object from the pool
ExportingProcess exportingProcess = pool.borrowObject(); System.out.println("Thread " + threadNo +
": Object with process no. " + exportingProcess.getProcessNo() + " was borrowed"); // do something
// ... // for-loop is just for simulation
for (int i = 0; i < 100000; i++) {
} // return ExportingProcess instance back to the pool
pool.returnObject(exportingProcess); System.out.println("Thread " + threadNo +
": Object with process no. " + exportingProcess.getProcessNo() + " was returned");
}
}
package easypool;

import org.junit.After;
import org.junit.Before;
import org.junit.Test; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; public class TestObjectPool
{
private ObjectPool<ExportingProcess> pool; private AtomicLong processNo = new AtomicLong(0); @Before
public void setUp() {
// Create a pool of objects of type ExportingProcess. Parameters:
// 1) Minimum number of special ExportingProcess instances residing in the pool = 4
// 2) Maximum number of special ExportingProcess instances residing in the pool = 10
// 3) Time in seconds for periodical checking of minIdle / maxIdle conditions in a separate thread = 5.
// When the number of ExportingProcess instances is less than minIdle, missing instances will be created.
// When the number of ExportingProcess instances is greater than maxIdle, too many instances will be removed.
// If the validation interval is negative, no periodical checking of minIdle / maxIdle conditions
// in a separate thread take place. These boundaries are ignored then.
pool = new ObjectPool<ExportingProcess>(4, 10, 5)
{
protected ExportingProcess createObject() {
// create a test object which takes some time for creation
return new ExportingProcess("/home/temp/", processNo.incrementAndGet());
}
};
} @After
public void tearDown() {
pool.shutdown();
} @Test
public void testObjectPool() {
ExecutorService executor = Executors.newFixedThreadPool(8); // execute 8 tasks in separate threads
executor.execute(new ExportingTask(pool, 1));
executor.execute(new ExportingTask(pool, 2));
executor.execute(new ExportingTask(pool, 3));
executor.execute(new ExportingTask(pool, 4));
executor.execute(new ExportingTask(pool, 5));
executor.execute(new ExportingTask(pool, 6));
executor.execute(new ExportingTask(pool, 7));
executor.execute(new ExportingTask(pool, 8)); executor.shutdown();
try {
executor.awaitTermination(30, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

测试》》》》》》》》》》》》》》》》》》》》》

package test;
public class StringFormat {
public String format(String str)
{
return "formated:"+str;
}
}
package test;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject; public class StringFormatFactory
extends BasePooledObjectFactory<StringFormat> { @Override
public StringFormat create() {
System.out.println("create object");
return new StringFormat();
} /**
* Use the default PooledObject implementation.
*/
@Override
public PooledObject<StringFormat> wrap(StringFormat buffer) {
return new DefaultPooledObject<StringFormat>(buffer);
} /**
* When an object is returned to the pool, clear the buffer.
*/
@Override
public void passivateObject(PooledObject<StringFormat> pooledObject) {
System.out.println("Object been returned to pool");
} // for all other methods, the no-op implementation
// in BasePooledObjectFactory will suffice
}
package test;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List; import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; public class StringProcessor { private ObjectPool<StringFormat> pool; public StringProcessor(ObjectPool<StringFormat> pool) {
this.pool = pool;
} /**
* Dumps the contents of the {@link Reader} to a String, closing the
* {@link Reader} when done.
*/
public void process(List<String> strList) {
for (String str : strList) {
Thread thread = new StringProcessThread(pool, str);
thread.start();
} //设置等待两秒,等待线程结束
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public static void main(String[] args) throws IOException { GenericObjectPoolConfig conf = new GenericObjectPoolConfig();
conf.setMaxTotal(3);
conf.setMaxIdle(2);
conf.setMinIdle(2); StringProcessor stringProcessor = new StringProcessor(
new GenericObjectPool<StringFormat>(new StringFormatFactory(),conf));
List<String> strList = new ArrayList<String>();
strList.add("123");
strList.add("456");
strList.add("789");
strList.add("111");
strList.add("222");
strList.add("333");
stringProcessor.process(strList);
}
}
package test;
import org.apache.commons.pool2.ObjectPool; public class StringProcessThread extends Thread {
private ObjectPool<StringFormat> pool;
private String toProcessStr; public StringProcessThread(ObjectPool<StringFormat> pool,
String toProcessStr) {
this.pool = pool;
this.toProcessStr = toProcessStr;
} public void run() {
StringFormat stringFormat = null;
try {
stringFormat = pool.borrowObject();
String formattedStr = stringFormat.format(toProcessStr);
System.out.println(formattedStr);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (stringFormat != null) {
pool.returnObject(stringFormat);
}
} catch (Exception e) {
e.printStackTrace();
}
}
} }

Apache common pool2 对象池的更多相关文章

  1. apache common pool2原理与实战

    完整源码,请帮我点个star哦! 原文地址为https://www.cnblogs.com/haixiang/p/14783955.html,转载请注明出处! 简介 对象池顾名思义就是存放对象的池,与 ...

  2. JedisCluster中应用的Apache Commons Pool对象池技术

    对象池技术在服务器开发上应用广泛.在各种对象池的实现中,尤其以数据库的连接池最为明显,可以说是每个服务器必须实现的部分.   apache common pool 官方文档可以参考:https://c ...

  3. commons.pool2 对象池的使用

    commons.pool2 对象池的使用 ? 1 2 3 4 5 <dependency>     <groupId>org.apache.commons</groupI ...

  4. Apache Commons-pool实现对象池(包括带key对象池)

    Commons-pool是一个apache开源组织下的众多项目的一个.其被广泛地整合到众多需要对象池功能的项目中. 官网:http://commons.apache.org/proper/common ...

  5. Java中对象池的本质是什么?(实战分析版)

    简介 对象池顾名思义就是存放对象的池,与我们常听到的线程池.数据库连接池.http连接池等一样,都是典型的池化设计思想. 对象池的优点就是可以集中管理池中对象,减少频繁创建和销毁长期使用的对象,从而提 ...

  6. Java网络与多线程系列之1:实现一个简单的对象池

    前言 为什么要从对象池开始呢,先从一个网络IO操作的demo说起 比如下面这段代码,显而易见已经在代码中使用了一个固定大小的线程池,所以现在的重点在实现Runnble接口的匿名对象上,这个对象每次创建 ...

  7. Java--对象池化技术 org.apache.commons.pool2.ObjectPool

    org.apache.commons.pool2.ObjectPool提供了对象池,开发的小伙伴们可以直接使用来构建一个对象池 使用该对象池具有两个简单的步骤: 1.创建对象工厂,org.apache ...

  8. Apache Common-pool2对象池分析和应用

    Apache Common-pool2包提供了一个通用的对象池技术的实现.可以很方便的基于它来实现自己的对象池,比如DBCP和Jedis他们的内部对象池的实现就是依赖于Common-pool2. 对象 ...

  9. 基于Apache组件,分析对象池原理

    池塘里养:Object: 一.设计与原理 1.基础案例 首先看一个基于common-pool2对象池组件的应用案例,主要有工厂类.对象池.对象三个核心角色,以及池化对象的使用流程: import or ...

随机推荐

  1. 树链剖分(单点更新,求区间最值,区间求和Bzoj1036)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 5759  Solved: 2383 [Submi ...

  2. sql xpath 查找包含

    select xcontent.query('/root//*[contains(text()[1], ''中'')]'), column1 from table

  3. demo16Toast

    /Users/alamps/AndroidStudioProjects/demo16Toast/demo16Toast/src/main/res/layout/activity_main.xml &l ...

  4. 南阳oj27题

    水池数目 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上 ...

  5. js 获取select 中option 的个数

    //document.writeln(document.getElementById("sel").options.length); //document.writeln(docu ...

  6. NOIP200505谁拿了最多的奖学金

    NOIP200505谁拿了最多的奖学金 Description 某校的惯例是在每学期的期末考试之后发放奖学金.发放的奖学金共有五种,获取的条件各自不同: 1)      院士奖学金,每人8000元,期 ...

  7. javascript 深拷贝

    javascript存在两种拷贝:浅拷贝.深拷贝. 它们最大的区别在于引用类型的拷贝上:浅拷贝复制的是引用(指针),深拷贝复制的是里面的数据. 由于以上原因,在下例中 浅拷贝修改的值影响了声明的对象a ...

  8. 161109、windows下查看端口占用情况

    1.开始---->运行---->cmd,或者是window+R组合键,调出命令窗口 2.输入命令:netstat -ano,列出所有端口的情况.在列表中我们观察被占用的端口,比如是4915 ...

  9. C#(winform)浏览按钮

    FolderBrowserDialog folderBrowser = new FolderBrowserDialog();            //folderBrowser.SelectedPa ...

  10. 如何查看Linux操作系统版本

    1. 查看内核版本命令: 360kb.com:~> cat /proc/version Linux version 2.6.32-358.el6.x86_64 (mockbuild@c6b8.b ...