对象池——利弊与使用场景

对象池使用

通常我们如此实现一个业务对象池,实现org.apache.commons.pool2.*的一些接口。

/**
 * @author zhangshuo
 *
 */
@Slf4j
public class ResourceLoaderFactory extends BasePooledObjectFactory<ResourceLoader> {

	/**
	 * 单例工厂
	 * 
	 * @return
	 */
	public static ResourceLoaderFactory getInstance() {
		return ResourceFactoryHolder.resourceLoaderFactory;
	}

	private static class ResourceLoaderFactoryHolder {
		public final static ResourceLoaderFactory resourceLoaderFactory= new ResourceLoaderFactory();
	}

	private final GenericObjectPool<ResourceLoader> objectsPool;

	public ResourceLoaderFactory() {
		GenericObjectPoolConfig config = new GenericObjectPoolConfig();
		config.setMaxTotal(1024);
		config.setMaxIdle(50);
		config.setMinIdle(8);
		// 当Pool中没有对象时不等待,而是直接new个新的
		config.setBlockWhenExhausted(false);
		AbandonedConfig abandonConfig = new AbandonedConfig();
		abandonConfig.setRemoveAbandonedTimeout(300);
		abandonConfig.setRemoveAbandonedOnBorrow(true);
		abandonConfig.setRemoveAbandonedOnMaintenance(true);
		objectsPool = new GenericObjectPool<ResourceLoader>(this, config, abandonConfig);
	}

	public ResourceLoader takeResourceLoader() throws Exception {
		try {
			return objectsPool.borrowObject();
		} catch (Exception e) {
			log.error("ResourceLoader error:{}",e);
		}
		return create();
	}

	@Override
	public ResourceLoader create() throws Exception {
		return ResourceLoader.builder().build();
	}

	@Override
	public PooledObject<ResourceLoader> wrap(ResourceLoader obj) {
		return new DefaultPooledObject<ResourceLoader>(obj);
	}

	public void returnObject(ResourceLoader loader) {
		loader.reset();
		objectsPool.returnObject(loader);
	}
}

对象池的优点

复用池中对象,消除创建对象、回收对象 所产生的内存开销、cpu开销以及(若跨网络)产生的网络开销.

常见的使用对象池有:在使用socket时(包括各种连接池)、线程等等

对象池的缺点:

  • 现在Java的对象分配操作不比c语言的malloc调用慢, 对于轻中量级的对象, 分配/释放对象的开销可以忽略不计;
  • 并发环境中, 多个线程可能(同时)需要获取池中对象, 进而需要在堆数据结构上进行同步或者因为锁竞争而产生阻塞, 这种开销要比创建销毁对象的开销高数百倍;
  • 由于池中对象的数量有限, 势必成为一个可伸缩性瓶颈;
  • 很难正确的设定对象池的大小, 如果太小则起不到作用, 如果过大, 则占用内存资源高,

对象池有其特定的适用场景:

  • 受限的, 不需要可伸缩性的环境(cpu\内存等物理资源有限): cpu性能不够强劲, 内存比较紧张, 垃圾收集, 内存抖动会造成比较大的影响, 需要提高内存管理效率, 响应性比吞吐量更为重要;
  • 数量受限的资源, 比如数据库连接;
  • 创建成本高昂的对象, 可斟酌是否池化, 比较常见的有线程池(ThreadPoolExecutor), 字节数组池等;

http://www.infoq.com/cn/news/2015/07/ClojureWerkz

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值