    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}