/* ================================================================== * Created [2009-4-27 下午11:32:55] by Jon.King * ================================================================== * TSS * ================================================================== * mailTo:jinpujun@hotmail.com * Copyright (c) Jon.King, 2009-2012 * ================================================================== */ package com.jinhe.tss.core.cachepool; import com.jinhe.tss.core.cachepool.container.ContainerFactory; import com.jinhe.tss.core.cachepool.container.IPoolContainer; import com.jinhe.tss.core.exception.BusinessException; import com.jinhe.tss.core.util.BeanUtil; /** * <p> ObjectPool.java </p> * * 缓存对象池 * * @author Jon.King 2006-12-28 */ public class ObjectPool extends AbstractPool implements ICleaner{ // 对象池属性 private IPoolContainer free; // 空闲的对象池 private IPoolContainer using; // 使用中的对象池 private static int cleanerCount = 0; private Cleaner cleaner; //清理器 private InitThread initer; public ObjectPool(){ } /** * 初始化指定数量的对象放入池中。 * 本方法将产生一个新的线程来初始化这些对象。 * 本方法跟release()方法是相对立的。 * @param num */ public final void init() { released = false; Class<?> collectionType = BeanUtil.createClassByName(getCacheStrategy().getPoolCollectionClass()); if (!IPoolContainer.class.isAssignableFrom(collectionType)) throw new BusinessException("指定的池集合类类型非法: " + collectionType.getName() + " (必须实现cachepool.container.IPoolContainer接口)"); ContainerFactory factory = ContainerFactory.getInstance(); free = free != null? free : factory.create(collectionType.getName(), getCacheStrategy().getCode() + "_free"); using = using != null? using : factory.create(collectionType.getName(), getCacheStrategy().getCode() + "_using"); addObjectPoolListener(new ObjectPoolListener()); //为缓存池添加一个监听器 startInitThread(getCacheStrategy().getInitNum().intValue()); initCleaner(); log.info("缓存池(" + strategy.getName() + ")初始化成功!"); } /** * 启动初始化线程 * @param num */ void startInitThread(int num){ if (num == 0) return; int maxSize = getCacheStrategy().getPoolSize().intValue(); if (num > 0 && (maxSize == 0 || num <= maxSize)) { shutDownIniter(); (initer = new InitThread(num)).start(); } else throw new IllegalArgumentException("初始化缓冲池的num参数非法"); } /** * 创建检查间隔最少为5秒的清除线程。 * 本方法包级私有 */ public void initCleaner(){ shutDownCleaner(); if (strategy.getCyclelife().longValue() > 0){ long cyclelife = strategy.getCyclelife().longValue(); long iVal = cyclelife == 0 ? 1000*60*60*24 : Math.max(1000*5, cyclelife / 5); (cleaner = new Cleaner(this, iVal)).start(); } } /** * 销毁 cleaner, initer 线程 */ private void shutDownCleaner() { if (cleaner != null) { cleaner.halt(); try { cleaner.join(); //等待线程死亡 } catch (InterruptedException e) { log.error("停止旧的cleaner线程时被中断", e); } cleaner = null; } } private void shutDownIniter() { if (initer != null){ initer.halt(); try { initer.join(); //等待线程死亡 } catch (InterruptedException e) { log.error("停止initer线程时被中断", e); } initer = null; } } public final void release(boolean forced) { if (released) return; released = true; shutDownCleaner(); shutDownIniter(); synchronized (this) { int rel = 0, failed = 0; // 销毁所有的缓存项(包括尚在使用中的) if (forced) { for (CacheableKey key : using.getKeys()) { try { destroyObject(free.get(key)); rel++; } catch (Exception e) { failed++; log.error("无法释放池中的缓存项目", e); } } using.clear(); } else { if (using.size() > 0) log.info("等待<使用中的>缓存项 被 check in pool..."); while (using.size() > 0) { try { wait(); // 等待,当连接被checkIn回来时,监听器会调用pool的notifyAll()通知这里 } catch (InterruptedException e) { } } } // 销毁当前所有空闲状态的缓存项 for (CacheableKey key : free.getKeys()) { try { destroyObject(free.get(key)); rel++; } catch (Exception e) { failed++; log.error("无法释放池中的缓存项目", e); } } free.clear(); String s = "成功释放 " + rel + " 个缓存项"; if (failed > 0) { s += " (有 " + failed + " 个缓存项释放失败)"; } log.info(s); firePoolEvent(ObjectPoolEvent.POOL_RELEASED); listeners.clear(); } } /** * 线程执行清除池中过期的对象。 * 当对象尚在使用中,线程将会等待对象返回。对象返回时将触发线程再次执行清除。 */ private final class Cleaner extends Thread { private ObjectPool pool; private long interval; // 定期清除缓存池时间间隔 private boolean stopped; // 缓存Cleaner是否已经被挂起 Cleaner(ObjectPool pool, long interval) { this.setName("CleanerThread_" + Integer.toString(cleanerCount++)); // 设置线程名称 this.pool = pool; this.interval = interval; } public void start() { stopped = false; super.start(); } /** * 安全的停止线程的运行,将线程挂起 */ public void halt() { if (!isHalted()) { stopped = true; interrupt(); // 必要的时间再将线程唤醒 } } /** * 返回线程的状态,是否被挂起 */ public boolean isHalted() { return stopped; } /** * 处理过期的对象 */ public void run() { while (pool.cleaner == Thread.currentThread() && !stopped) { try { if (!stopped) { sleep(interval); } synchronized (pool) { if (!pool.purge()) { pool.wait(); //使本cleaner线程进入等待休眠状态。(线程进入该对象的休息室waitSet) //当pool池的checkIn或者putIn事件被触发时,唤醒本cleaner线程 } } } catch (InterruptedException e) { log.debug("运行cleaner线程时出错!", e); } } } } /** * 线程执行初始化池中对象。 */ private final class InitThread extends Thread{ private int num; private boolean stopped = false; private InitThread(int num){ this.num = Math.min(getCacheStrategy().getPoolSize().intValue(), Math.max(num, 0)); // Ensure 0 < num < poolSize. } public void halt() { stopped = true; } /** * 生成指定数量的缓存对象。如果池中已有对象存在且数量小于指定数目,则线程将补足不足的对象数目。 */ public void run(){ while ( getSize() < num ){ if(stopped){ log.debug("初始化线程已经停止!"); return; } try{ Cacheable o = arithmetic.create(getCacheStrategy().getCyclelife()); if (o == null){ String errorMsg = ObjectPool.this.getName() + "池初始化时无法创建对象"; log.error(errorMsg); throw new BusinessException(errorMsg); }else{ putObject(o.getKey(), o.getValue()); } }catch (Exception e){ log.error("无法在池中初始化对象", e); stopped = true; //如果本次循环创建对象失败,则将线程标记设置为停用,下次循环判断的时候即可推出循环,以免进入死循环。 } } log.debug(ObjectPool.this.getName() + "池中初始化了 " + getSize() + " 个新的对象"); } } public IPoolContainer getFree() { return free; } public IPoolContainer getUsing() { return using; } public final synchronized int getSize() { return (free == null ? 0 : free.size()) + (using == null ? 0 : using.size()); } }