论坛首页 Java企业应用论坛

轻量级的对象池

浏览 3170 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-10-10  

Pool在N多环境下碰到,比如连接池、线程池、缓存池...

当某一对象从池中取得,那只有等待被用完放回去以后,其它的线程才能再次从池中获取。对象在池中是具有自己生命周期:创建、验证、使用、销毁等等。Pool的方式也许是最好的方式用来管理同一的资源。

 

运用的场景:

高频率的运用同一的资源

对象大且很消耗内存(DB连接)

需要长时间的初始化

IO消耗大

对象非线程安全

 

Apache Commons Pool 提供其轻量级的作用,不过它并未使用JDK1.5之后的Execute的框架,这是我觉得可能比较可惜的,就如同Proxool跟Boncp比较,性能指标提升最大一个就是分区和使用Execute、Guava等性能提升比较大的工具包。

 

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
	 *            初始化最小的对象池中对象创建数量
	 */
	public ObjectPool(final int minIdle) {
		// initialize pool
		initialize(minIdle);
	}

	/**
	 * Pool创建
	 * 
	 * @param minIdle
	 *            最小的数量
	 * @param maxIdle
	 *            最大数量
	 * @param validationInterval
	 *            检查最大/最小的池中的对象的频率
	 */
	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);
	}

	/**
	 * 获取对象,如果没有,那就创建且返回
	 * 
	 * @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());
		}
	}
}

 抽象池中主要提供borrowObject 是在具体实现类中可存放任意的对象,附件中存有测试代码。

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics