org.appng.api.search.BlockingQueueAccessor Maven / Gradle / Ivy
/*
* Copyright 2011-2021 the original author or authors.
*
* 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 org.appng.api.search;
import java.lang.reflect.ParameterizedType;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
* A {@link BlockingQueue}-based implementation for consumer-producer-scenarios.
* Note that all available operations are blocking!
*
* @author Matthias Müller
*
* @see Producer
* @see Consumer
*/
public abstract class BlockingQueueAccessor {
private static final int DEFAULT_QUEUE_SIZE = 100;
private final BlockingQueue queue;
/**
* Creates a new {@code BlockingQueueAccessor} with the given queue size.
*
* @param queueSize
* the size of the internal {@link BlockingQueue}
*/
protected BlockingQueueAccessor(int queueSize) {
queue = new ArrayBlockingQueue(queueSize);
}
/**
* Creates a new {@code BlockingQueueAccessor} with a queue size of 100}.
*/
protected BlockingQueueAccessor() {
this(DEFAULT_QUEUE_SIZE);
}
/**
* Puts the given {@code element} into the queue.
* This is a blocking operation!
*
* @param element
* the element of type {@code } to put to the queue
*
* @throws InterruptedException
* if interrupted while waiting
*/
public void put(E element) throws InterruptedException {
queue.put(element);
}
/**
* Puts the given {@code element} into the queue, waiting up to {@code timeoutMillis} milliseconds if
* necessary.
* This is a blocking operation!
*
* @param element
* the element of type {@code } to put into the queue
* @param timeoutMillis
* the time to wait in milliseconds
*
* @return {@code true} if the element could be added before the timeout, {@code false} otherwise
*
* @throws InterruptedException
* if interrupted while waiting
*/
public boolean put(E element, long timeoutMillis) throws InterruptedException {
return queue.offer(element, timeoutMillis, TimeUnit.MILLISECONDS);
}
/**
* Puts the given {@code element} into the queue, waiting up to {@code timeoutMillis} milliseconds if necessary. If
* no element could be added, a {@link TimeoutException} is thrown.
* This is a blocking operation!
*
* @param element
* the element of type {@code } to put to the queue
* @param timeoutMillis
* the time to wait in milliseconds
*
* @throws InterruptedException
* if interrupted while waiting
* @throws TimeoutException
* if a timeout occurred while waiting
*/
public void putWithTimeout(E element, long timeoutMillis) throws InterruptedException, TimeoutException {
boolean offered = put(element, timeoutMillis);
if (!offered) {
throw new TimeoutException(element + " could not be added after " + timeoutMillis + " "
+ TimeUnit.MILLISECONDS.name().toLowerCase() + ", queue limit exceeded!");
}
}
/**
* Retrieves and removes the head of the queue.
* This is a blocking operation!
*
* @return an element of type {@code }
*
* @throws InterruptedException
* if interrupted while waiting
*/
public E get() throws InterruptedException {
return queue.take();
}
/**
* Retrieves and removes the head of the queue, waiting up to {@code timeoutMillis} milliseconds if necessary. If no
* element could be retrieved, {@code null} is returned.
* This is a blocking operation!
*
* @param timeoutMillis
* the time to wait in milliseconds
*
* @return an element of type {@code }, or {@code null} if no element could be retrieved in {@code timeoutMillis}
* milliseconds
*
* @throws InterruptedException
* if interrupted while waiting
*/
public E get(long timeoutMillis) throws InterruptedException {
return queue.poll(timeoutMillis, TimeUnit.MILLISECONDS);
}
/**
* Retrieves and removes the head of the queue, waiting up to {@code timeoutMillis} milliseconds if necessary. If no
* element could be retrieved, a {@link TimeoutException} is thrown.
* This is a blocking operation!
*
* @param timeoutMillis
* the time to wait in milliseconds
*
* @return an element of type {@code }
*
* @throws InterruptedException
* if interrupted while waiting
* @throws TimeoutException
* if a timeout occurred while waiting
*/
public E getWithTimeout(long timeoutMillis) throws InterruptedException, TimeoutException {
E element = get(timeoutMillis);
if (null == element) {
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
Class> itemType = (Class>) parameterizedType.getActualTypeArguments()[0];
throw new TimeoutException("no " + itemType.getName() + " returned after " + timeoutMillis + " "
+ TimeUnit.MILLISECONDS.name().toLowerCase());
}
return element;
}
protected BlockingQueue getBlockingQueue() {
return queue;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy