在我们的项目中往往有这样的需求:我们需要用的一些对象是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线程安全
分享到:
相关推荐
本实例探讨的是如何利用Java中的Socket对象以及线程连接池技术,特别是`GenericObjectPool`来提高程序性能和效率。首先,我们需要理解Socket和线程连接池的基本概念。 **Socket**: Socket是网络通信的一种接口,它...
4. **ThriftPoolFactory**:创建并初始化连接池的工厂类,它会根据配置信息创建PoolableConnectionFactory,并将其与实际的连接池实现(如GenericObjectPool)结合。 使用这个Thrift连接池时,开发者需要按照如下...
try (GenericObjectPool<StringWrapper> pool = new GenericObjectPool(new StringPoolFactory(), config)) { for (int i = 0; i ; i++) { StringWrapper stringWrapper = pool.borrowObject(); System.out....
在本项目实践中,我们探索了如何利用Spring Boot框架构建一个人工智能驱动的搜索引擎,特别是针对大规模人脸搜索的应用。这个系统的核心在于集成Milvus向量搜索引擎,它允许我们高效地处理和检索高维数据,如人脸...
2. **初始化GenericObjectPool**: 使用PooledObjectFactory实例,你可以创建一个GenericObjectPool实例。这里可以设置各种配置属性,如最大活动对象数(`maxTotal`)、最大单线程内活动对象数(`maxIdle`)、最小空闲...
2. **对象池实现(GenericObjectPool)**:`GenericObjectPool` 是一个通用的对象池实现,它可以接受任何实现了 `PoolableObjectFactory` 的对象。它提供了线程安全的池管理和对象获取策略,如最大池大小、最大空闲...
`GenericObjectPool`是对象池的实现,它可以配置各种池化策略,如最大活动对象数、空闲超时时间等。 在实际应用中,你可以通过以下步骤使用Apache Commons Pool: 1. 创建一个实现`PoolableObjectFactory`的类,...
4. **配置选项**:`GenericObjectPool`有很多可配置的参数,比如最大活动对象数、最大空闲对象数、测试对象是否有效的间隔时间等,这些参数可以调整以优化池的行为。 5. **异常处理**:Pool2库提供了健全的异常处理...
在1.6这个版本中,它包含了一系列的类和接口,如Poolable接口、PooledObject接口、GenericObjectPool类等,这些组件共同构成了一个完整的对象池管理系统。 1. **Poolable接口**:这个接口定义了对象池中的对象应该...
这个库的核心类包括`ObjectPool`接口、`BaseObjectPool`抽象类以及`GenericObjectPool`和`GenericKeyedObjectPool`等实现。`ObjectPool`接口定义了对象池的基本操作,如获取、返回和清理对象。`BaseObjectPool`提供...
例如,当与Redis结合使用时,可以创建一个自定义的RedisConnectionFactory,实现PooledObjectFactory接口,然后创建一个GenericObjectPool实例,将连接工厂作为参数传入。这样,每当需要一个新的Redis连接时,就可以...
在"commons-pool-1.5.4"这个版本中,我们可以找到关于对象池化的核心类和接口,例如`GenericObjectPool`和`PooledObjectFactory`。 1. **核心类:GenericObjectPool** `GenericObjectPool`是Apache Commons Pool中...
o POOL-152: GenericObjectPool can block forever in borrowObject when the pool is exhausted and a newly created object fails validation. When borrowing an object if a new object is created but ...
5. **KeyedObjectPool**和**KeyedPoolableObjectFactory**:与GenericObjectPool类似,但支持基于键的对象池,适用于需要根据某个键(如数据库连接字符串)获取对象的情况。 **在数据库连接管理中的应用(DBCP):*...
4. `GenericObjectPool`: 这是默认的对象池实现,可以配置各种参数以调整池的行为,如最大池大小、最大空闲时间、测试对象前/后的策略等。 5. `GenericKeyedObjectPool`: 类似于`GenericObjectPool`,但支持键值对...
它包括核心的Pool接口和一些实现类,如GenericObjectPool和PooledObjectFactory,它们是构建和操作对象池的关键组件。 Pool接口定义了对象池的基本操作,如borrowObject(获取对象)、returnObject(归还对象)和...
GenericObjectPool<String> pool = new GenericObjectPool(factory, config); String obj = pool.borrowObject(); // 使用对象 pool.returnObject(obj); ``` 5. **最佳实践** - **合理设置池大小**:根据...
10. **使用示例**:在实际应用中,开发者通常会创建一个`GenericObjectPool`实例,然后使用`PooledObjectFactory`创建一个对象池,接着在需要时调用`borrowObject()`获取对象,使用完毕后调用`returnObject()`归还...
该错误信息表明,在初始化Spring容器时遇到了问题,具体是在创建名为`dataSource`的Bean时失败,进一步的原因是找不到`org.apache.commons.pool.impl.GenericObjectPool`类的定义。这个类是Apache Commons Pool库中...
GenericObjectPool<ExecutorService> threadPool = new GenericObjectPool(factory, poolConfig); // 使用线程池执行任务 for (int i = 0; i ; i++) { threadPool.borrowObject().submit(new Callable() { @...