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.multiset;
018
019import java.util.Comparator;
020
021import org.apache.commons.collections4.SortedMultiSet;
022
023/**
024 * Decorates another {@link SortedMultiSet} to synchronize its behavior
025 * for a multithreaded environment.
026 * <p>
027 * Methods are synchronized, then forwarded to the decorated multiset.
028 * Iterators must be separately synchronized around the loop.
029 * </p>
030 *
031 * @param <E> The type held in the multiset.
032 * @since 4.6.0
033 */
034public class SynchronizedSortedMultiSet<E> extends SynchronizedMultiSet<E> implements SortedMultiSet<E> {
035
036    /** Serialization version */
037    private static final long serialVersionUID = 20260705L;
038
039    /**
040     * Factory method to create a synchronized sorted multiset.
041     *
042     * @param <E> The type of the elements in the multiset
043     * @param multiset  The multiset to decorate, must not be null
044     * @return A new synchronized SortedMultiSet
045     * @throws NullPointerException if multiset is null
046     */
047    public static <E> SynchronizedSortedMultiSet<E> synchronizedSortedMultiSet(final SortedMultiSet<E> multiset) {
048        return new SynchronizedSortedMultiSet<>(multiset);
049    }
050
051    /**
052     * Constructor that wraps (not copies).
053     *
054     * @param multiset  The multiset to decorate, must not be null
055     * @throws NullPointerException if multiset is null
056     */
057    protected SynchronizedSortedMultiSet(final SortedMultiSet<E> multiset) {
058        super(multiset);
059    }
060
061    /**
062     * Constructor that wraps (not copies).
063     *
064     * @param multiset  The multiset to decorate, must not be null
065     * @param lock  The lock to use, must not be null
066     * @throws NullPointerException if multiset or lock is null
067     */
068    protected SynchronizedSortedMultiSet(final SortedMultiSet<E> multiset, final Object lock) {
069        super(multiset, lock);
070    }
071
072    @Override
073    public Comparator<? super E> comparator() {
074        synchronized (lock) {
075            return decorated().comparator();
076        }
077    }
078
079    /**
080     * Gets the multiset being decorated.
081     *
082     * @return The decorated multiset
083     */
084    @Override
085    protected SortedMultiSet<E> decorated() {
086        return (SortedMultiSet<E>) super.decorated();
087    }
088
089    @Override
090    public E first() {
091        synchronized (lock) {
092            return decorated().first();
093        }
094    }
095
096    @Override
097    public E last() {
098        synchronized (lock) {
099            return decorated().last();
100        }
101    }
102
103}