/*
* Copyright (c) 2008-2012, Hazel Bilisim Ltd. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.util;
import java.util.AbstractQueue;
import java.util.Collection;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
public class DoubleBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E> {
private final Object notEmptyLock = new Object();
private final Queue<E> priorityQueue = new ConcurrentLinkedQueue<E>();
private final Queue<E> defaultQueue = new ConcurrentLinkedQueue<E>();
public void put(E e) throws InterruptedException {
defaultQueue.offer(e);
synchronized (notEmptyLock) {
//noinspection CallToNotifyInsteadOfNotifyAll
notEmptyLock.notify();
}
}
@Override
public Iterator<E> iterator() {
throw new UnsupportedOperationException();
}
public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException {
put(e);
return true;
}
@Override
public int size() {
return priorityQueue.size() + defaultQueue.size();
}
public E take() throws InterruptedException {
return poll(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}
public E poll(long timeout, TimeUnit unit) throws InterruptedException {
E e = tryPoll();
if (e != null) return e;
long timeLeft = unit.toMillis(timeout);
while (e == null && timeLeft > 0) {
long start = System.currentTimeMillis();
synchronized (notEmptyLock) {
notEmptyLock.wait(100);
}
e = tryPoll();
long now = System.currentTimeMillis();
timeLeft -= (now - start);
start = now;
}
return e;
}
E tryPoll() {
E e = priorityQueue.poll();
if (e == null) {
e = defaultQueue.poll();
}
return e;
}
public E poll() {
return tryPoll();
}
public int remainingCapacity() {
return Integer.MAX_VALUE;
}
public int drainTo(Collection<? super E> c) {
throw new UnsupportedOperationException();
}
public int drainTo(Collection<? super E> c, int maxElements) {
throw new UnsupportedOperationException();
}
public boolean offer(E e) {
return defaultQueue.offer(e);
}
public E peek() {
throw new UnsupportedOperationException();
}
}