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线程安全
### GenericObjectPool 钝化的含义及其作用 在 Apache Commons Pool2 中,`GenericObjectPool` 提供了一种机制来钝化(Passivate)对象。钝化是指将活跃状态的对象转换为一种休眠或待机的状态,以便它们可以被安全地存储到池中[^4]。 当一个对象通过 `returnObject` 方法返回给池时,通常会执行一系列操作以确保该对象能够再次被借用而不会引发问题。这些操作可能包括: 1. **钝化(passivate)**:调用 `PooledObjectFactory.passivateObject` 方法,用于将对象从活动状态转变为非活动状态。这一步骤对于释放资源或重置对象内部状态非常重要。 2. **验证(validate)**:在某些配置下,可能会对钝化后的对象进行验证,以确认其仍然处于可用状态。 3. **清理(destroy)**:如果对象无法通过验证,则会被销毁而不是重新放入池中。 #### 钝化的作用 钝化的主要目的是确保对象能够在不使用期间保持稳定,并减少不必要的开销。具体来说,钝化有以下几个重要作用: - **资源回收**:一些对象在其生命周期内可能持有外部资源(如数据库连接、文件句柄等),钝化过程可以帮助释放这些资源[^2]。 - **状态重置**:许多对象在使用过程中会发生状态变化,如果不加以处理,在下次借用时可能导致不可预测的行为。钝化可以通过重置对象状态来避免此类问题。 - **延长寿命**:通过对对象进行钝化处理,可以在一定程度上延缓对象的老化速度,从而降低频繁创建和销毁带来的性能损耗。 以下是基于 `GenericObjectPool` 的简单代码示例,展示如何自定义钝化行为: ```java public class MyObject { private String data; public void setData(String data) { this.data = data; } public String getData() { return data; } } public class MyObjectFactory implements PooledObjectFactory<MyObject> { @Override public PooledObject<MyObject> makeObject() throws Exception { return new DefaultPooledObject<>(new MyObject()); } @Override public void destroyObject(PooledObject<MyObject> p) throws Exception { System.out.println("Destroying object"); } @Override public boolean validateObject(PooledObject<MyObject> p) { return true; // 假设所有对象都有效 } @Override public void activateObject(PooledObject<MyObject> p) throws Exception { System.out.println("Activating object"); } @Override public void passivateObject(PooledObject<MyObject> p) throws Exception { System.out.println("Passivating object and resetting state..."); p.getObject().setData(null); // 重置数据字段 } } ``` 在这个例子中,每当对象被归还至池时,都会触发 `passivateObject` 方法,其中包含了对其状态的重置逻辑。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值