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

com.lti.utils.synchronization.ProducerConsumerQueue Maven / Gradle / Ivy

There is a newer version: 1.0.2-jitsi
Show newest version
package com.lti.utils.synchronization;

import com.lti.utils.collections.*;

/**
 * A synchronized queue where get/put waits if needed.
 *
 * @author Ken Larson
 */
public class ProducerConsumerQueue
{
    private final Queue q = new Queue();
    private final int sizeLimit;

    public ProducerConsumerQueue()
    {
        super();
        sizeLimit = -1;
    }

    public ProducerConsumerQueue(int sizeLimit)
    {
        this.sizeLimit = sizeLimit;
    }

    public synchronized T get() throws InterruptedException // java programming
                                                            // note: making a
                                                            // method
                                                            // synchronized is
                                                            // the same as
                                                            // putting the
                                                            // contents of the
                                                            // method insided
                                                            // synchronized
                                                            // (this){}
    {
        while (q.isEmpty())
        {
            // try
            // {
            wait(); // java programming note: this causes the lock to be
                    // released until we are notified
            // }
            // catch (InterruptedException e) { }
        }
        final T o = q.dequeue();
        // if (sizeLimit > 0 && q.size() == sizeLimit - 1)
        notifyAll();
        return o;
    }

    /** @return returnOnTimeout if timeout. */
    public synchronized T get(long timeout, T returnOnTimeout)
            throws InterruptedException
    {
        // TODO: what if null were queued?
        while (q.isEmpty())
        {
            final long t1 = System.currentTimeMillis();
            wait(timeout);
            if ((System.currentTimeMillis() - t1) > timeout)
            {
                return returnOnTimeout; // timeout
            }
        }
        final T o = q.dequeue();
        // if (sizeLimit > 0 && q.size() == sizeLimit - 1)
        notifyAll();
        return o;
    }

    public synchronized boolean isEmpty()
    {
        return q.size() == 0;
    }

    public synchronized boolean isFull()
    {
        return sizeLimit > 0 && q.size() >= sizeLimit;
    }

    public synchronized void put(T value) throws InterruptedException
    {
        while (sizeLimit > 0 && q.size() >= sizeLimit)
        {
            // try
            // {
            wait();
            // }
            // catch (InterruptedException e) { }
        }

        q.enqueue(value);
        notifyAll();
    }

    /**
     * @return false if timeout, true otherwise
     */
    public synchronized boolean put(T value, long timeout)
            throws InterruptedException
    {
        while (sizeLimit > 0 && q.size() >= sizeLimit)
        {
            // try
            // {
            long t1 = System.currentTimeMillis();
            wait(timeout);
            if ((System.currentTimeMillis() - t1) > timeout)
            {
                return false; // timeout
            }
            // }
            // catch (InterruptedException e)
            // {
            // }
        }

        q.enqueue(value);
        notifyAll();
        return true;
    }

    public synchronized int size()
    {
        return q.size();
    }

    public int sizeLimit()
    {
        return sizeLimit;
    }

    public synchronized void waitUntilEmpty() throws InterruptedException
    {
        while (!q.isEmpty())
        {
            wait(); // java programming note: this causes the lock to be
                    // released until we are notified
        }
    }

    public synchronized void waitUntilNotEmpty() throws InterruptedException
    {
        while (q.isEmpty())
        {
            wait(); // java programming note: this causes the lock to be
                    // released until we are notified
        }
    }

    /**
     * @return true if success, false if timeout.
     *
     */
    public synchronized boolean waitUntilNotEmpty(long timeout)
            throws InterruptedException
    {
        final long start = System.currentTimeMillis();
        while (q.isEmpty())
        {
            final long now = System.currentTimeMillis();
            final long alreadyWaited = now - start;
            final long waitRemaining = timeout - alreadyWaited;
            if (waitRemaining < 1)
                return false;
            wait(waitRemaining); // java programming note: this causes the lock
                                 // to be released until we are notified
        }
        return !q.isEmpty();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy