import org.apache.log4j.Logger;
/**
* 循环队列小工具,可以包括如下功能:
* 1. 可以放入对象,可以取出
* 2. 当放入对象已满,可以判断,对象出口是否关闭,如果关闭那么就代替最旧的对象,如果出口比较慢
* 可以等待一下
* 3. 出口能获得对象池中最旧的那个对象。
* 4. 服务端不能依赖于客户端的链接,能处理客户端的断开和链接。
*
* @author zjfan
*
*/
public class CycleQueueContainer {
private static final Logger log = Logger.getLogger(CycleQueueContainer.class);
private static CycleQueueContainer instance;
private CycleQueueContainer(){
}
public synchronized static CycleQueueContainer getInstance(){
if(instance == null){
instance = new CycleQueueContainer();
}
return instance;
}
private Node nodeHead;
private Node nodeTail;
private boolean fullAlarm = false;
private boolean sleepSign = false;
private int threadSleepSecond = 60;
private String addObjThreadName = "Thread-0";
public void setThreadSleepSecond(int threadSleepSecond) {
this.threadSleepSecond = threadSleepSecond;
}
public void setAddObjThreadName(String addObjThreadName){
this.addObjThreadName = addObjThreadName;
}
public void setUpCycleQueue(int queueLength){
Node nodeRe = new Node();
Node nodeNew = nodeRe;
for(int index = 0; index < queueLength; index++){
Node node = new Node();
nodeNew.next = node;
nodeNew = node;
}
nodeNew.next = nodeRe;
nodeHead = nodeRe;
nodeTail = nodeRe;
log.info("循环队列建立成功,队列长度:" + queueLength);
}
/**
* 对外窗口
*
* @return
*/
public Object getObjFroContainer(){
return operateContainer(false, null);
}
/**
* 对外窗口
*
* @param obj
*/
public void addObjToContainer(Object obj){
operateContainer(true, obj);
}
/**
* 主要负责添加对象线程是否休息
*
* @param operateType
* @param obj
* @return
*/
private Object operateContainer(boolean operateType, Object obj){
Object obj_re = operateQueue(operateType, obj);
if(operateType){
String threadname = Thread.currentThread().getName();
if(sleepSign && addObjThreadName.equals(threadname)){
log.info("容器已满,且出口没有关闭,不能继续添加对象,线程Thread-0休息:" + threadSleepSecond + "秒");
try {
java.util.concurrent.TimeUnit.SECONDS.sleep(threadSleepSecond);
} catch (InterruptedException e) {
e.printStackTrace();
}
sleepSign = false;
}
}
return obj_re;
}
/**
* 同步操作循环队列
*
* @param operateType true: 向队列加对象,false: 从队列取数据;
* @param obj
* @return
*/
private synchronized Object operateQueue(boolean operateType, Object obj){
if(operateType){
//向队列加对象
addObject(obj);
return null;
} else {
//从队列取数据
return pollObject();
}
}
private void addObject(Object obj){
if(isQueueFull()){
if(!fullAlarm){
//出口取对象比较慢,那么就设置fullAlarm为true,取
sleepSign = true;
fullAlarm = true;
} else {
//认为出口已经停掉,那么就覆盖nodeTail所指的对象
// log.debug("容器满,目前判断出口已经停掉,所以新对象要覆盖旧对象..");
nodeTail = nodeTail.next;
nodeHead.obj = obj;
nodeHead = nodeHead.next;
}
} else {
nodeHead.obj = obj;
nodeHead = nodeHead.next;
}
}
private Object pollObject(){
if(isQueueEmpty()){
return null;
} else {
fullAlarm = false;
Object obj = nodeTail.obj;
nodeTail = nodeTail.next;
return obj;
}
}
/**
* 判断队列是否满
*
* @return
*/
private boolean isQueueFull(){
if(nodeHead.next == nodeTail){
return true;
} else {
return false;
}
}
/**
* 判断队列是否为空
*
* @return
*/
private boolean isQueueEmpty(){
if(nodeHead == nodeTail){
return true;
} else {
return false;
}
}
private class Node{
Object obj;
Node next;
}
}