/* ==================================================================
* 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.extend.assignment;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.log4j.Logger;
import com.jinhe.tss.core.cachepool.CacheManager;
import com.jinhe.tss.core.cachepool.extend.thread.IThreadPool;
import com.jinhe.tss.core.cachepool.strategy.CacheConstants;
/**
* <p> OutputRecordsManager.java </p>
* <br>输出记录类操作的管理类超类。 可输出日志、点击率、访问量等信息
* <br>
* <br>本超类中设置了一个存放记录的缓存,当缓存中的记录数到达最大值时,
* <br>则会把缓存中的记录交给一个RecordsOutputTask任务,并调用工作线程池来执行该任务。
* <br>
* <br>本超类中同时还启用了一个守护的记录输出进程,当距离上次输出记录的时间达到最长等待时间时,
* <br>则不管缓存是否已满只要有记录就都强制输出。
* <br>
*
* @author Jon.King 2007-2-15
*/
public abstract class OutputRecordsManager {
protected Logger log = Logger.getLogger(this.getClass());
private boolean isReady = true; //池是否已经初始化正确
private final static int maxSize = 12; //满12条就输出记录
private final static int maxTime = 3*60*1000; //定时输出记录的间隔时间:3分钟
private List<Object> bufferedRecords = Collections.synchronizedList(new ArrayList<Object>());
protected IThreadPool tpool;
public OutputRecordsManager(){
try{
CacheManager manager = CacheManager.getInstance();
tpool = (IThreadPool) manager.getCachePool(CacheConstants.THREAD_POOL);
}catch(Exception e){
isReady = false;
log.error("初始化" + this.getClass() + "时初始化缓存池出错", e);
}
new FlushThread().start(); // 启动定时输出日志的收获线程
}
/**
* 输出记录信息到缓存中,到临界值时输出缓存中记录到远程服务器端数据库中
* @param dto
*/
public synchronized void output(Object record){
if(isReady) {
bufferedRecords.add(record);
}
if(size() >= getMaxSize() ){
flush();
}
}
private int size(){ return bufferedRecords == null ? 0 : bufferedRecords.size(); }
/**
* 强制输出记录(为异步,调用线程池中的一个线程来完成)
*/
public void flush(){
final List<Object> temp = bufferedRecords;
reset();
excuteTask(temp);
}
private void reset(){
bufferedRecords = Collections.synchronizedList(new ArrayList<Object>());
}
/**
* 执行输出记录(为异步,调用线程池中的一个线程来完成)
* @param records
*/
protected abstract void excuteTask(List<Object> records);
protected int getMaxSize(){ return maxSize; }
protected int getMaxTime(){ return maxTime;}
/**
* @author Jon.King 2007-2-15
*
* 记录定时输出,时间一满不管是否满了都输出去
*/
private class FlushThread extends Thread{
public void run() {
while (true) {
try {
sleep(getMaxTime()); /** 定期休眠,醒来后输出记录 */
if(size() > 0 ) {
flush();
}
} catch (InterruptedException e) {
log.error("运行OutputRecordsManager.FlushThread线程时出错!", e);
}
}
}
}
}