All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.collections.buffer.BoundedBuffer Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 32.0.0.Final
Show newest version
/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.apache.commons.collections.buffer;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Iterator;

import org.apache.commons.collections.BoundedCollection;
import org.apache.commons.collections.Buffer;
import org.apache.commons.collections.BufferOverflowException;
import org.apache.commons.collections.BufferUnderflowException;
import org.apache.commons.collections.iterators.AbstractIteratorDecorator;

/**
 * Decorates another Buffer to ensure a fixed maximum size.
 * 

* Note: This class should only be used if you need to add bounded * behaviour to another buffer. If you just want a bounded buffer then * you should use {@link BoundedFifoBuffer} or {@link CircularFifoBuffer}. *

* The decoration methods allow you to specify a timeout value. * This alters the behaviour of the add methods when the buffer is full. * Normally, when the buffer is full, the add method will throw an exception. * With a timeout, the add methods will wait for up to the timeout period * to try and add the elements. * * @author James Carman * @author Stephen Colebourne * @version $Revision: 646777 $ $Date: 2008-04-10 13:33:15 +0100 (Thu, 10 Apr 2008) $ * @since Commons Collections 3.2 */ public class BoundedBuffer extends SynchronizedBuffer implements BoundedCollection { /** The serialization version. */ private static final long serialVersionUID = 1536432911093974264L; /** The maximum size. */ private final int maximumSize; /** The timeout milliseconds. */ private final long timeout; /** * Factory method to create a bounded buffer. *

* When the buffer is full, it will immediately throw a * BufferOverflowException on calling add(). * * @param buffer the buffer to decorate, must not be null * @param maximumSize the maximum size, must be size one or greater * @return a new bounded buffer * @throws IllegalArgumentException if the buffer is null * @throws IllegalArgumentException if the maximum size is zero or less */ public static BoundedBuffer decorate(Buffer buffer, int maximumSize) { return new BoundedBuffer(buffer, maximumSize, 0L); } /** * Factory method to create a bounded buffer that blocks for a maximum * amount of time. * * @param buffer the buffer to decorate, must not be null * @param maximumSize the maximum size, must be size one or greater * @param timeout the maximum amount of time to wait in milliseconds * @return a new bounded buffer * @throws IllegalArgumentException if the buffer is null * @throws IllegalArgumentException if the maximum size is zero or less */ public static BoundedBuffer decorate(Buffer buffer, int maximumSize, long timeout) { return new BoundedBuffer(buffer, maximumSize, timeout); } //----------------------------------------------------------------------- /** * Constructor that wraps (not copies) another buffer, making it bounded * waiting only up to a maximum amount of time. * * @param buffer the buffer to wrap, must not be null * @param maximumSize the maximum size, must be size one or greater * @param timeout the maximum amount of time to wait * @throws IllegalArgumentException if the buffer is null * @throws IllegalArgumentException if the maximum size is zero or less */ protected BoundedBuffer(Buffer buffer, int maximumSize, long timeout) { super(buffer); if (maximumSize < 1) { throw new IllegalArgumentException(); } this.maximumSize = maximumSize; this.timeout = timeout; } //----------------------------------------------------------------------- public Object remove() { synchronized (lock) { Object returnValue = getBuffer().remove(); lock.notifyAll(); return returnValue; } } public boolean add(Object o) { synchronized (lock) { timeoutWait(1); return getBuffer().add(o); } } public boolean addAll(final Collection c) { synchronized (lock) { timeoutWait(c.size()); return getBuffer().addAll(c); } } public Iterator iterator() { return new NotifyingIterator(collection.iterator()); } private void timeoutWait(final int nAdditions) { // method synchronized by callers if (nAdditions > maximumSize) { throw new BufferOverflowException( "Buffer size cannot exceed " + maximumSize); } if (timeout <= 0) { // no wait period (immediate timeout) if (getBuffer().size() + nAdditions > maximumSize) { throw new BufferOverflowException( "Buffer size cannot exceed " + maximumSize); } return; } final long expiration = System.currentTimeMillis() + timeout; long timeLeft = expiration - System.currentTimeMillis(); while (timeLeft > 0 && getBuffer().size() + nAdditions > maximumSize) { try { lock.wait(timeLeft); timeLeft = expiration - System.currentTimeMillis(); } catch (InterruptedException ex) { PrintWriter out = new PrintWriter(new StringWriter()); ex.printStackTrace(out); throw new BufferUnderflowException( "Caused by InterruptedException: " + out.toString()); } } if (getBuffer().size() + nAdditions > maximumSize) { throw new BufferOverflowException("Timeout expired"); } } public boolean isFull() { // size() is synchronized return (size() == maxSize()); } public int maxSize() { return maximumSize; } //----------------------------------------------------------------------- /** * BoundedBuffer iterator. */ private class NotifyingIterator extends AbstractIteratorDecorator { public NotifyingIterator(Iterator it) { super(it); } public void remove() { synchronized (lock) { iterator.remove(); lock.notifyAll(); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy