GenericObjectPool

在我们的项目中往往有这样的需求:我们需要用的一些对象是thread-unsafe的,但是它又承受着高并发的压力,同时往往我们有可能无法去对它改造(或许它是第3方提供的);抑或他的一次创建和销毁非常的耗时。以上两种场景的解决方案用对象池再适合不过了。
本文将解答一下几个问题:
#1什么是对象池
#2怎么使用对象池
#3其实用原理是什么
#4实战中应该注意什么

什么是对象池
简单的来讲,对象池就是我们构造一个集合,提前将需要池化的对象构造一些保存起来,当需要的时候从池子里面取出一个给索取者,索取者用完后还回给池子以便其他索取者可用获得。
要点:1.提前缓存;2.有借有还

怎么使用

//构造一个池化对象
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

public class ReadDataNetFactory extends BasePooledObjectFactory<ReadNetData> {

@Override
public ReadNetData create() {
return new ReadNetData();
}

@Override
public PooledObject<ReadNetData> wrap(ReadNetData buffer) {
return new DefaultPooledObject<ReadNetData>(buffer);
}

@Override
public PooledObject<ReadNetData> makeObject() throws Exception {
// TODO Auto-generated method stub
return super.makeObject();
}
@Override
public void destroyObject(PooledObject<ReadNetData> p) throws Exception {
// TODO Auto-generated method stub
super.destroyObject(p);
}
@Override
public boolean validateObject(PooledObject<ReadNetData> p) {
// TODO Auto-generated method stub
return super.validateObject(p);
}
@Override
public void activateObject(PooledObject<ReadNetData> p) throws Exception {
// TODO Auto-generated method stub
super.activateObject(p);
}
@Override
public void passivateObject(PooledObject<ReadNetData> p) throws Exception {
// TODO Auto-generated method stub
super.passivateObject(p);
}
}
//使用对象池
import org.apache.commons.pool2.impl.GenericObjectPool;

public class UseReadNetData {

GenericObjectPool<ReadNetData> pool = new GenericObjectPool<ReadNetData>(new ReadDataNetFactory());

private void init(int maxIdle,int maxTotal,long maxWaitMillis) throws Exception{
pool.setMaxIdle(maxIdle);
pool.setMaxTotal(maxTotal);
pool.setMaxWaitMillis(maxWaitMillis);

for(int i =0;i<maxTotal;i++){
pool.addObject();
System.out.println("add object============>"+i);
}
}

public static void main(String[] args) throws Exception {
UseReadNetData user = new UseReadNetData();
user.init(2, 5, 3000);
for(int i =0;i<100;i++){
new Thread(new Reader(user.pool)).start();
}
}
}

class Reader implements Runnable{

private GenericObjectPool<ReadNetData> pool;
public Reader( GenericObjectPool<ReadNetData> pool){
this.pool = pool;
}
public void run() {
ReadNetData read = null;
try {
read = pool.borrowObject();
System.err.println("00000000000000000000"+read.readDate());
} catch (Exception e) {
e.printStackTrace();
}finally{
if(read!= null){

pool.returnObject(read);
}
}
}

}

ObjectPool有很多种实现这里我们使用GenericObjectPool<T>。构造GenericObjectPool需要一个ObjectFactory.这里我使用BasePooledObjectFactory<T>。这里很好的体现了OO的单一责任原则。通过factory将的池化对象包裹成DefaultPooledObject,同时对象状态的维护也由
DefaultPooledObject自己维护。GenericObjectPool只负责pool的管理。
BasePooledObjectFactory中提供了一些在获得或者还回对象时可以对对象进行处理的方法。
要点:1.使用addObject初始化pool
2.使用borrowObject索取对象
3.使用returnObject还回对象

其原理是什么
GenericObjectPool内部构建集合来存储对象(idleObjects[LinkedBlockingDeque]和allObjects[Map]),每次调用其borrowObject方法索取对象时,从idleObjects中出队列一个对象。
当使用后使用returnObject还回给Pool.
还有很对方法请自行探索

实战中应该注意什么
1.提前初始化
2.有借有还
3.GenericObjectPool线程安全
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值