packagecomrt.util;importjava.util.AbstractQueue;importjava.util.Collection;importjava.util.Iterator;importjava.util.concurrent.BlockingQueue;importjava.util.concurrent.TimeUnit;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.ReentrantLock;importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;//双缓冲队列,线程安全
public class DoubleBufferedQueue extends AbstractQueue implements BlockingQueue, java.io.Serializable {private static final long serialVersionUID = 1011398447523020L;public static final int DEFAULT_QUEUE_CAPACITY = 5000000;public static final long DEFAULT_MAX_TIMEOUT = 0;public static final long DEFAULT_MAX_COUNT = 10;private Logger logger = LoggerFactory.getLogger(DoubleBufferedQueue.class.getName());/**The queued items*/
privateReentrantLock readLock;//写锁
privateReentrantLock writeLock;//是否满
privateCondition notFull;privateCondition awake;//读写数组
private transientE[] writeArray;private transientE[] readArray;//读写计数
private volatile intwriteCount;private volatile intreadCount;//写数组下标指针
private intwriteArrayTP;private intwriteArrayHP;//读数组下标指针
private intreadArrayTP;private intreadArrayHP;private intcapacity;public DoubleBufferedQueue(intcapacity) {//默认
this.capacity =DEFAULT_QUEUE_CAPACITY;if (capacity > 0) {this.capacity =capacity;
}
readArray= (E[]) newObject[capacity];
writeArray= (E[]) newObject[capacity];
readLock= newReentrantLock();
writeLock= newReentrantLock();
notFull=writeLock.newCondition();
awake=writeLock.newCondition();
}private voidinsert(E e) {
writeArray[writeArrayTP]=e;++writeArrayTP;++writeCount;
}privateE extract() {
E e=readArray[readArrayHP];
readArray[readArrayHP]= null;++readArrayHP;--readCount;returne;
}/*** switch condition: read queue is empty && write queue is not empty
*
* Notice:This function can only be invoked after readLock is grabbed,or may
* cause dead lock
*
*@paramtimeout
*@paramisInfinite
* : whether need to wait forever until some other thread awake
* it
*@return*@throwsInterruptedException*/
private long queueSwap(long timeout, boolean isInfinite) throwsInterruptedException {
writeLock.lock();try{if (writeCount <= 0) {//logger.debug("Write Count:" + writeCount//+ ", Write Queue is empty, do not switch!");
try{//logger.debug("Queue is empty, need wait....");
if (isInfinite && timeout <= 0) {
awake.await();return -1;
}else if (timeout > 0) {returnawake.awaitNanos(timeout);
}else{return 0;
}
}catch(InterruptedException ie) {
awake.signal();throwie;
}
}else{
E[] tmpArray=readArray;
readArray=writeArray;
writeArray=tmpArray;
readCount=writeCount;
readArrayHP= 0;
readArrayTP=writeArrayTP;
writeCount= 0;
writeArrayHP=readArrayHP;
writeArrayTP= 0;
notFull.signal();//logger.debug("Queue switch successfully!");
return 0;
}
}finally{
writeLock.unlock();
}
}
@Overridepublic boolean offer(E e, long timeout, TimeUnit unit) throwsInterruptedException {if (e == null) {throw newNullPointerException();
}long nanoTime = 0;if (timeout > 0) {
nanoTime=unit.toNanos(timeout);
}
writeLock.lockInterruptibly();try{for (int i = 0; i < DEFAULT_MAX_COUNT; i++) {if (writeCount
insert(e);if (writeCount == 1) {
awake.signal();
}return true;
}//Time out
if (nanoTime <= 0) {//logger.debug("offer wait time out!");
return false;
}//keep waiting
try{//logger.debug("Queue is full, need wait....");
nanoTime =notFull.awaitNanos(nanoTime);
}catch(InterruptedException ie) {
notFull.signal();throwie;
}
}
}finally{
writeLock.unlock();
}return false;
}//取
@Overridepublic E poll(long timeout, TimeUnit unit) throwsInterruptedException {long nanoTime = 0;if (timeout > 0) {
nanoTime=unit.toNanos(timeout);
}
readLock.lockInterruptibly();try{if (nanoTime > 0) {for (int i = 0; i < DEFAULT_MAX_COUNT; i++) {if (readCount > 0) {returnextract();
}if (nanoTime <= 0) {//logger.debug("poll time out!");
return null;
}
nanoTime= queueSwap(nanoTime, false);
}
}else{if (readCount > 0) {returnextract();
}
queueSwap(nanoTime,false);if (readCount > 0) {returnextract();
}
}
}finally{
readLock.unlock();
}return null;
}//等待500毫秒
@OverridepublicE poll() {
E ret= null;try{
ret=poll(DEFAULT_MAX_TIMEOUT, TimeUnit.MILLISECONDS);
}catch(Exception e) {
ret= null;
}returnret;
}//查看
@OverridepublicE peek() {
E e= null;
readLock.lock();try{if (readCount > 0) {
e=readArray[readArrayHP];
}
}finally{
readLock.unlock();
}returne;
}//默认500毫秒
@Overridepublic booleanoffer(E e) {boolean ret = false;try{
ret=offer(e, DEFAULT_MAX_TIMEOUT, TimeUnit.MILLISECONDS);
}catch(Exception e2) {
ret= false;
}returnret;
}
@Overridepublic void put(E e) throwsInterruptedException {//never need to//block
offer(e, DEFAULT_MAX_TIMEOUT, TimeUnit.MILLISECONDS);
}
@Overridepublic E take() throwsInterruptedException {returnpoll(DEFAULT_MAX_TIMEOUT, TimeUnit.MILLISECONDS);
}
@Overridepublic intremainingCapacity() {return this.capacity;
}
@Overridepublic int drainTo(Collection super E>c) {return 0;
}
@Overridepublic int drainTo(Collection super E> c, intmaxElements) {return 0;
}
@Overridepublic Iteratoriterator() {return null;
}//当前读队列中还有多少个
@Overridepublic intsize() {int size = 0;
readLock.lock();try{
size=readCount;
}finally{
readLock.unlock();
}returnsize;
}/*** 当前已写入的队列大小
**/
public intWriteSize() {int size = 0;
writeLock.lock();try{
size=writeCount;
}finally{
writeLock.unlock();
}returnsize;
}public intunsafeReadSize() {returnreadCount;
}public intunsafeWriteSize() {returnwriteCount;
}public intcapacity() {returncapacity;
}publicString toMemString() {return "--read: " + readCount + "/" + capacity + "--write: " + writeCount + "/" +capacity;
}//清理
/** public void clear() { readLock.lock(); writeLock.lock(); try { readCount
* = 0; readArrayHP = 0; writeCount = 0; writeArrayTP = 0;
* //logger.debug("Queue clear successfully!"); } finally {
* writeLock.unlock(); readLock.unlock(); } }*/}