java 伸缩面板实现_java 可伸缩阻塞队列实现

importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.ArrayBlockingQueue;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;/*** 实现可调整大小的阻塞队列,支持数据迁移平衡reader,writer读取吸入速度,达到最大吞吐

*@authorhanjie

**/

public classRecordBuffer {public static final Record CLOSE_RECORD = newRecord() {

@OverridepublicObject getColumnValue(String columnName) {//TODO Auto-generated method stub

return null;

}

};public static final Record SWITCH_QUEUE_RECORD = newRecord() {

@OverridepublicObject getColumnValue(String columnName) {//TODO Auto-generated method stub

return null;

}

};public Lock switchingQueueLock = newReentrantLock();public Condition readerSwitched =switchingQueueLock.newCondition();public Condition writerSwitched =switchingQueueLock.newCondition();public Condition switchFinished =switchingQueueLock.newCondition();public volatile boolean readerSwitchSuccess = true;public volatile boolean writerSwitchSuccess = true;public volatile boolean switchingQueue = false;public volatile boolean closed = false;private volatile ArrayBlockingQueuequeue;privateTaskCounter taskCounter;public RecordBuffer(TaskCounter taskCounter, intsize) {this.queue = new ArrayBlockingQueue(size);this.taskCounter =taskCounter;

}public void resize(intnewSize) {try{if(closed){return;

}

switchingQueueLock.lock();try{//double check下,要不可能writer收到CLOSED_record已经 退出了。writerSwitched.await() 会hang住

if(closed){return;

}this.switchingQueue = true;

ArrayBlockingQueue oldQueue =queue;

queue= new ArrayBlockingQueue(newSize);this.readerSwitchSuccess = false;this.writerSwitchSuccess = false;//先拯救下writer,可能writer刚好阻塞到take上,失败也没关系,说明老队列不空,writer不会阻塞到take

oldQueue.offer(SWITCH_QUEUE_RECORD);while (!writerSwitchSuccess) {

writerSwitched.await();

}//writer先切换队列,然后reader可能阻塞在最后一个put上,清空下老队列拯救reader,让它顺利醒来

transferOldQueueRecordsToNewQueue(oldQueue);while (!readerSwitchSuccess) {

readerSwitched.await();

}//前面的清空,刚好碰到reader要put最后一个,非阻塞式清空动作就有残留最后一个put

transferOldQueueRecordsToNewQueue(oldQueue);this.switchingQueue = false;this.switchFinished.signalAll();

}finally{

switchingQueueLock.unlock();

}

}catch(InterruptedException e) {

Thread.currentThread().interrupt();throw newRuntimeException(e);

}

}private void transferOldQueueRecordsToNewQueue(ArrayBlockingQueueoldQueue)throwsInterruptedException {

List oldRecords = new ArrayList(oldQueue.size());

Record record= null;while ((record = oldQueue.poll()) != null) {

oldRecords.add(record);

}//转移老队列剩下的记录到新队列

for (int i = 0; i < oldRecords.size(); i++) {

queue.put(oldRecords.get(i));

}

}public voidclose() {this.closed = true;

switchingQueueLock.lock();try{//如果正在切换队列, 等切换做完才能,发送最后一个CLOSE

while(switchingQueue) {

switchFinished.await();

}this.queue.put(CLOSE_RECORD);

}catch(InterruptedException e) {

Thread.currentThread().interrupt();throw newRuntimeException(e);

}finally{

switchingQueueLock.unlock();

}

}public voidput(Record record) {try{if (!queue.offer(record)) {

taskCounter.incrBufferFullCount();if (!readerSwitchSuccess) {

notifyReaderSwitchSuccess();

}

queue.put(record);

}

taskCounter.incrReadCount();

}catch(InterruptedException e) {

Thread.currentThread().interrupt();throw newRuntimeException(e);

}

}private voidnotifyReaderSwitchSuccess() {

System.out.println("reader switch");

switchingQueueLock.lock();try{

readerSwitchSuccess= true;

readerSwitched.signalAll();

}finally{

switchingQueueLock.unlock();

}

}publicRecord take() {try{

Record record=queue.poll();//如果拿到了切换记录,则切换队列重试

if(record ==SWITCH_QUEUE_RECORD){if (!writerSwitchSuccess) {

notifyWriterSwitchSuccess();

}

record=queue.poll();

}if (record == null) {

taskCounter.incrBufferEmptyCount();//调用take先检查是否正在切换,保证拿到新的队列

if (!writerSwitchSuccess) {

notifyWriterSwitchSuccess();

}

record=queue.take();//如果很不幸刚好在take阻塞时候,切换,只能发送一个切换记录将其唤醒

if(record ==SWITCH_QUEUE_RECORD){if (!writerSwitchSuccess) {

notifyWriterSwitchSuccess();

}

record=queue.take();

}

}if (record ==CLOSE_RECORD) {if (!writerSwitchSuccess) {

notifyWriterSwitchSuccess();

}return null;

}

taskCounter.incrWriteCount();returnrecord;

}catch(InterruptedException e) {

Thread.currentThread().interrupt();throw newRuntimeException(e);

}

}private voidnotifyWriterSwitchSuccess() {

System.out.println("writer switch");

switchingQueueLock.lock();try{

writerSwitchSuccess= true;

writerSwitched.signalAll();

}finally{

switchingQueueLock.unlock();

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值