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 behavior for a multithreaded environment.
025 * <p>
026 * Methods are synchronized, then forwarded to the decorated queue. Iterators must be separately synchronized around the
027 * loop.
028 * </p>
029 *
030 * @param <E> the type of the elements in the collection
031 * @since 4.2
032 */
033public class SynchronizedQueue<E> extends SynchronizedCollection<E> implements Queue<E> {
034
035    /** Serialization version */
036    private static final long serialVersionUID = 1L;
037
038    /**
039     * Factory method to create a synchronized queue.
040     *
041     * @param <E>
042     *            the type of the elements in the queue
043     * @param queue
044     *            the queue to decorate, must not be null
045     * @return a new synchronized Queue
046     * @throws NullPointerException
047     *             if queue is null
048     */
049    public static <E> SynchronizedQueue<E> synchronizedQueue(final Queue<E> queue) {
050        return new SynchronizedQueue<>(queue);
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    @Override
107    public int hashCode() {
108        synchronized (lock) {
109            return decorated().hashCode();
110        }
111    }
112
113    @Override
114    public boolean offer(final E e) {
115        synchronized (lock) {
116            return decorated().offer(e);
117        }
118    }
119
120    @Override
121    public E peek() {
122        synchronized (lock) {
123            return decorated().peek();
124        }
125    }
126
127    @Override
128    public E poll() {
129        synchronized (lock) {
130            return decorated().poll();
131        }
132    }
133
134    @Override
135    public E remove() {
136        synchronized (lock) {
137            return decorated().remove();
138        }
139    }
140
141}