001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.collections4.queue;
018
019import java.util.Queue;
020
021import org.apache.commons.collections4.collection.SynchronizedCollection;
022
023/**
024 * Decorates another {@link Queue} to synchronize its behaviour for a multi-threaded environment.
025 * <p>
026 * Methods are synchronized, then forwarded to the decorated queue. Iterators must be separately synchronized around the
027 * loop.
028 *
029 * @param <E> the type of the elements in the collection
030 * @since 4.2
031 */
032public class SynchronizedQueue<E> extends SynchronizedCollection<E> implements Queue<E> {
033
034    /** Serialization version */
035    private static final long serialVersionUID = 1L;
036
037    /**
038     * Factory method to create a synchronized queue.
039     *
040     * @param <E>
041     *            the type of the elements in the queue
042     * @param queue
043     *            the queue to decorate, must not be null
044     * @return a new synchronized Queue
045     * @throws NullPointerException
046     *             if queue is null
047     */
048    public static <E> SynchronizedQueue<E> synchronizedQueue(final Queue<E> queue) {
049        return new SynchronizedQueue<>(queue);
050    }
051
052    // -----------------------------------------------------------------------
053    /**
054     * Constructor that wraps (not copies).
055     *
056     * @param queue
057     *            the queue to decorate, must not be null
058     * @throws NullPointerException
059     *             if queue is null
060     */
061    protected SynchronizedQueue(final Queue<E> queue) {
062        super(queue);
063    }
064
065    /**
066     * Constructor that wraps (not copies).
067     *
068     * @param queue
069     *            the queue to decorate, must not be null
070     * @param lock
071     *            the lock to use, must not be null
072     * @throws NullPointerException
073     *             if queue or lock is null
074     */
075    protected SynchronizedQueue(final Queue<E> queue, final Object lock) {
076        super(queue, lock);
077    }
078
079    /**
080     * Gets the queue being decorated.
081     *
082     * @return the decorated queue
083     */
084    @Override
085    protected Queue<E> decorated() {
086        return (Queue<E>) super.decorated();
087    }
088
089    @Override
090    public E element() {
091        synchronized (lock) {
092            return decorated().element();
093        }
094    }
095
096    @Override
097    public boolean equals(final Object object) {
098        if (object == this) {
099            return true;
100        }
101        synchronized (lock) {
102            return decorated().equals(object);
103        }
104    }
105
106    // -----------------------------------------------------------------------
107
108    @Override
109    public int hashCode() {
110        synchronized (lock) {
111            return decorated().hashCode();
112        }
113    }
114
115    @Override
116    public boolean offer(final E e) {
117        synchronized (lock) {
118            return decorated().offer(e);
119        }
120    }
121
122    @Override
123    public E peek() {
124        synchronized (lock) {
125            return decorated().peek();
126        }
127    }
128
129    @Override
130    public E poll() {
131        synchronized (lock) {
132            return decorated().poll();
133        }
134    }
135
136    @Override
137    public E remove() {
138        synchronized (lock) {
139            return decorated().remove();
140        }
141    }
142
143}