    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 *      https://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}