SynchronizedMultiSet.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.collections4.multiset;

  18. import java.util.Set;

  19. import org.apache.commons.collections4.MultiSet;
  20. import org.apache.commons.collections4.collection.SynchronizedCollection;

  21. /**
  22.  * Decorates another {@link MultiSet} to synchronize its behavior
  23.  * for a multithreaded environment.
  24.  * <p>
  25.  * Methods are synchronized, then forwarded to the decorated multiset.
  26.  * Iterators must be separately synchronized around the loop.
  27.  * </p>
  28.  *
  29.  * @param <E> the type held in the multiset.
  30.  * @since 4.1
  31.  */
  32. public class SynchronizedMultiSet<E> extends SynchronizedCollection<E> implements MultiSet<E> {

  33.     /**
  34.      * Synchronized Set for the MultiSet class.
  35.      *
  36.      * @param <T> the type held in this Set.
  37.      */
  38.     static class SynchronizedSet<T> extends SynchronizedCollection<T> implements Set<T> {
  39.         /** Serialization version */
  40.         private static final long serialVersionUID = 20150629L;

  41.         /**
  42.          * Constructs a new instance.
  43.          * @param set  the set to decorate
  44.          * @param lock  the lock to use, shared with the multiset
  45.          */
  46.         SynchronizedSet(final Set<T> set, final Object lock) {
  47.             super(set, lock);
  48.         }
  49.     }

  50.     /** Serialization version */
  51.     private static final long serialVersionUID = 20150629L;

  52.     /**
  53.      * Factory method to create a synchronized multiset.
  54.      *
  55.      * @param <E> the type of the elements in the multiset
  56.      * @param multiset  the multiset to decorate, must not be null
  57.      * @return a new synchronized MultiSet
  58.      * @throws NullPointerException if multiset is null
  59.      */
  60.     public static <E> SynchronizedMultiSet<E> synchronizedMultiSet(final MultiSet<E> multiset) {
  61.         return new SynchronizedMultiSet<>(multiset);
  62.     }

  63.     /**
  64.      * Constructor that wraps (not copies).
  65.      *
  66.      * @param multiset  the multiset to decorate, must not be null
  67.      * @throws NullPointerException if multiset is null
  68.      */
  69.     protected SynchronizedMultiSet(final MultiSet<E> multiset) {
  70.         super(multiset);
  71.     }

  72.     /**
  73.      * Constructor that wraps (not copies).
  74.      *
  75.      * @param multiset  the multiset to decorate, must not be null
  76.      * @param lock  the lock to use, must not be null
  77.      * @throws NullPointerException if multiset or lock is null
  78.      */
  79.     protected SynchronizedMultiSet(final MultiSet<E> multiset, final Object lock) {
  80.         super(multiset, lock);
  81.     }

  82.     @Override
  83.     public int add(final E object, final int count) {
  84.         synchronized (lock) {
  85.             return decorated().add(object, count);
  86.         }
  87.     }

  88.     /**
  89.      * Gets the multiset being decorated.
  90.      *
  91.      * @return the decorated multiset
  92.      */
  93.     @Override
  94.     protected MultiSet<E> decorated() {
  95.         return (MultiSet<E>) super.decorated();
  96.     }

  97.     @Override
  98.     public Set<Entry<E>> entrySet() {
  99.         synchronized (lock) {
  100.             final Set<MultiSet.Entry<E>> set = decorated().entrySet();
  101.             return new SynchronizedSet<>(set, lock);
  102.         }
  103.     }

  104.     @Override
  105.     public boolean equals(final Object object) {
  106.         if (object == this) {
  107.             return true;
  108.         }
  109.         synchronized (lock) {
  110.             return decorated().equals(object);
  111.         }
  112.     }

  113.     @Override
  114.     public int getCount(final Object object) {
  115.         synchronized (lock) {
  116.             return decorated().getCount(object);
  117.         }
  118.     }

  119.     @Override
  120.     public int hashCode() {
  121.         synchronized (lock) {
  122.             return decorated().hashCode();
  123.         }
  124.     }

  125.     @Override
  126.     public int remove(final Object object, final int count) {
  127.         synchronized (lock) {
  128.             return decorated().remove(object, count);
  129.         }
  130.     }

  131.     @Override
  132.     public int setCount(final E object, final int count) {
  133.         synchronized (lock) {
  134.             return decorated().setCount(object, count);
  135.         }
  136.     }

  137.     @Override
  138.     public Set<E> uniqueSet() {
  139.         synchronized (lock) {
  140.             final Set<E> set = decorated().uniqueSet();
  141.             return new SynchronizedSet<>(set, lock);
  142.         }
  143.     }

  144. }