Home | History | Annotate | Download | only in collect
      1 /*
      2  * Copyright (C) 2007 Google Inc.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.google.common.collect;
     18 
     19 import com.google.common.annotations.GwtCompatible;
     20 import com.google.common.annotations.GwtIncompatible;
     21 
     22 import java.io.IOException;
     23 import java.io.ObjectOutputStream;
     24 import java.io.Serializable;
     25 import java.util.Collection;
     26 import java.util.Comparator;
     27 import java.util.Iterator;
     28 import java.util.List;
     29 import java.util.ListIterator;
     30 import java.util.Map;
     31 import java.util.RandomAccess;
     32 import java.util.Set;
     33 import java.util.SortedSet;
     34 
     35 import javax.annotation.Nullable;
     36 
     37 import static com.google.common.base.Preconditions.checkNotNull;
     38 
     39 /**
     40  * Synchronized collection views. The returned synchronized collection views are
     41  * serializable if the backing collection and the mutex are serializable.
     42  *
     43  * <p>If a {@code null} is passed as the {@code mutex} parameter to any of this
     44  * class's top-level methods or inner class constructors, the created object
     45  * uses itself as the synchronization mutex.
     46  *
     47  * <p>This class should be used by other collection classes only.
     48  *
     49  * @author Mike Bostock
     50  * @author Jared Levy
     51  */
     52 @GwtCompatible
     53 final class Synchronized {
     54   private Synchronized() {}
     55 
     56   /** Abstract base class for synchronized views. */
     57   static class SynchronizedObject implements Serializable {
     58     private final Object delegate;
     59     protected final Object mutex;
     60 
     61     public SynchronizedObject(Object delegate, @Nullable Object mutex) {
     62       this.delegate = checkNotNull(delegate);
     63       this.mutex = (mutex == null) ? this : mutex;
     64     }
     65 
     66     protected Object delegate() {
     67       return delegate;
     68     }
     69 
     70     // No equals and hashCode; see ForwardingObject for details.
     71 
     72     @Override public String toString() {
     73       synchronized (mutex) {
     74         return delegate.toString();
     75       }
     76     }
     77 
     78     // Serialization invokes writeObject only when it's private.
     79     // The SynchronizedObject subclasses don't need a writeObject method since
     80     // they don't contain any non-transient member variables, while the
     81     // following writeObject() handles the SynchronizedObject members.
     82 
     83     private void writeObject(ObjectOutputStream stream) throws IOException {
     84       synchronized (mutex) {
     85         stream.defaultWriteObject();
     86       }
     87     }
     88 
     89     private static final long serialVersionUID = 0;
     90   }
     91 
     92   /**
     93    * Returns a synchronized (thread-safe) collection backed by the specified
     94    * collection using the specified mutex. In order to guarantee serial access,
     95    * it is critical that <b>all</b> access to the backing collection is
     96    * accomplished through the returned collection.
     97    *
     98    * <p>It is imperative that the user manually synchronize on the specified
     99    * mutex when iterating over the returned collection: <pre>  {@code
    100    *
    101    *  Collection<E> s = Synchronized.collection(
    102    *      new HashSet<E>(), mutex);
    103    *  ...
    104    *  synchronized (mutex) {
    105    *    Iterator<E> i = s.iterator(); // Must be in synchronized block
    106    *    while (i.hasNext()) {
    107    *      foo(i.next());
    108    *    }
    109    *  }}</pre>
    110    *
    111    * Failure to follow this advice may result in non-deterministic behavior.
    112    *
    113    * @param collection the collection to be wrapped in a synchronized view
    114    * @return a synchronized view of the specified collection
    115    */
    116   static <E> Collection<E> collection(
    117       Collection<E> collection, @Nullable Object mutex) {
    118     return new SynchronizedCollection<E>(collection, mutex);
    119   }
    120 
    121   /** @see Synchronized#collection */
    122   static class SynchronizedCollection<E> extends SynchronizedObject
    123       implements Collection<E> {
    124     public SynchronizedCollection(
    125         Collection<E> delegate, @Nullable Object mutex) {
    126       super(delegate, mutex);
    127     }
    128 
    129     @SuppressWarnings("unchecked")
    130     @Override protected Collection<E> delegate() {
    131       return (Collection<E>) super.delegate();
    132     }
    133 
    134     public boolean add(E e) {
    135       synchronized (mutex) {
    136         return delegate().add(e);
    137       }
    138     }
    139 
    140     public boolean addAll(Collection<? extends E> c) {
    141       synchronized (mutex) {
    142         return delegate().addAll(c);
    143       }
    144     }
    145 
    146     public void clear() {
    147       synchronized (mutex) {
    148         delegate().clear();
    149       }
    150     }
    151 
    152     public boolean contains(Object o) {
    153       synchronized (mutex) {
    154         return delegate().contains(o);
    155       }
    156     }
    157 
    158     public boolean containsAll(Collection<?> c) {
    159       synchronized (mutex) {
    160         return delegate().containsAll(c);
    161       }
    162     }
    163 
    164     public boolean isEmpty() {
    165       synchronized (mutex) {
    166         return delegate().isEmpty();
    167       }
    168     }
    169 
    170     public Iterator<E> iterator() {
    171       return delegate().iterator(); // manually synchronized
    172     }
    173 
    174     public boolean remove(Object o) {
    175       synchronized (mutex) {
    176         return delegate().remove(o);
    177       }
    178     }
    179 
    180     public boolean removeAll(Collection<?> c) {
    181       synchronized (mutex) {
    182         return delegate().removeAll(c);
    183       }
    184     }
    185 
    186     public boolean retainAll(Collection<?> c) {
    187       synchronized (mutex) {
    188         return delegate().retainAll(c);
    189       }
    190     }
    191 
    192     public int size() {
    193       synchronized (mutex) {
    194         return delegate().size();
    195       }
    196     }
    197 
    198     public Object[] toArray() {
    199       synchronized (mutex) {
    200         return delegate().toArray();
    201       }
    202     }
    203 
    204     public <T> T[] toArray(T[] a) {
    205       synchronized (mutex) {
    206         return delegate().toArray(a);
    207       }
    208     }
    209 
    210     private static final long serialVersionUID = 0;
    211   }
    212 
    213   /**
    214    * Returns a synchronized (thread-safe) set backed by the specified set using
    215    * the specified mutex. In order to guarantee serial access, it is critical
    216    * that <b>all</b> access to the backing set is accomplished through the
    217    * returned set.
    218    *
    219    * <p>It is imperative that the user manually synchronize on the specified
    220    * mutex when iterating over the returned set:  <pre>  {@code
    221    *
    222    *  Set<E> s = Synchronized.set(new HashSet<E>(), mutex);
    223    *  ...
    224    *  synchronized (mutex) {
    225    *    Iterator<E> i = s.iterator(); // Must be in synchronized block
    226    *    while (i.hasNext()) {
    227    *      foo(i.next());
    228    *    }
    229    *  }}</pre>
    230    *
    231    * Failure to follow this advice may result in non-deterministic behavior.
    232    *
    233    * @param set the set to be wrapped in a synchronized view
    234    * @return a synchronized view of the specified set
    235    */
    236   public static <E> Set<E> set(Set<E> set, @Nullable Object mutex) {
    237     return new SynchronizedSet<E>(set, mutex);
    238   }
    239 
    240   /** @see Synchronized#set */
    241   static class SynchronizedSet<E> extends SynchronizedCollection<E>
    242       implements Set<E> {
    243     public SynchronizedSet(Set<E> delegate, @Nullable Object mutex) {
    244       super(delegate, mutex);
    245     }
    246 
    247     @Override protected Set<E> delegate() {
    248       return (Set<E>) super.delegate();
    249     }
    250 
    251     @Override public boolean equals(Object o) {
    252       if (o == this) {
    253         return true;
    254       }
    255       synchronized (mutex) {
    256         return delegate().equals(o);
    257       }
    258     }
    259 
    260     @Override public int hashCode() {
    261       synchronized (mutex) {
    262         return delegate().hashCode();
    263       }
    264     }
    265 
    266     private static final long serialVersionUID = 0;
    267   }
    268 
    269   /**
    270    * Returns a synchronized (thread-safe) sorted set backed by the specified
    271    * sorted set using the specified mutex. In order to guarantee serial access,
    272    * it is critical that <b>all</b> access to the backing sorted set is
    273    * accomplished through the returned sorted set.
    274    *
    275    * <p>It is imperative that the user manually synchronize on the specified
    276    * mutex when iterating over the returned sorted set: <pre>  {@code
    277    *
    278    *  SortedSet<E> s = Synchronized.sortedSet(
    279    *      new TreeSet<E>(), mutex);
    280    *  ...
    281    *  synchronized (mutex) {
    282    *    Iterator<E> i = s.iterator(); // Must be in synchronized block
    283    *    while (i.hasNext()) {
    284    *      foo(i.next());
    285    *    }
    286    *  }}</pre>
    287    *
    288    * Failure to follow this advice may result in non-deterministic behavior.
    289    *
    290    * @param set the sorted set to be wrapped in a synchronized view
    291    * @return a synchronized view of the specified sorted set
    292    */
    293   static <E> SortedSet<E> sortedSet(SortedSet<E> set, @Nullable Object mutex) {
    294     return new SynchronizedSortedSet<E>(set, mutex);
    295   }
    296 
    297   /** @see Synchronized#sortedSet */
    298   static class SynchronizedSortedSet<E> extends SynchronizedSet<E>
    299       implements SortedSet<E> {
    300     public SynchronizedSortedSet(
    301         SortedSet<E> delegate, @Nullable Object mutex) {
    302       super(delegate, mutex);
    303     }
    304 
    305     @Override protected SortedSet<E> delegate() {
    306       return (SortedSet<E>) super.delegate();
    307     }
    308 
    309     public Comparator<? super E> comparator() {
    310       synchronized (mutex) {
    311         return delegate().comparator();
    312       }
    313     }
    314 
    315     public SortedSet<E> subSet(E fromElement, E toElement) {
    316       synchronized (mutex) {
    317         return sortedSet(delegate().subSet(fromElement, toElement), mutex);
    318       }
    319     }
    320 
    321     public SortedSet<E> headSet(E toElement) {
    322       synchronized (mutex) {
    323         return sortedSet(delegate().headSet(toElement), mutex);
    324       }
    325     }
    326 
    327     public SortedSet<E> tailSet(E fromElement) {
    328       synchronized (mutex) {
    329         return sortedSet(delegate().tailSet(fromElement), mutex);
    330       }
    331     }
    332 
    333     public E first() {
    334       synchronized (mutex) {
    335         return delegate().first();
    336       }
    337     }
    338 
    339     public E last() {
    340       synchronized (mutex) {
    341         return delegate().last();
    342       }
    343     }
    344 
    345     private static final long serialVersionUID = 0;
    346   }
    347 
    348   /**
    349    * Returns a synchronized (thread-safe) list backed by the specified list
    350    * using the specified mutex. In order to guarantee serial access, it is
    351    * critical that <b>all</b> access to the backing list is accomplished
    352    * through the returned list.
    353    *
    354    * <p>It is imperative that the user manually synchronize on the specified
    355    * mutex when iterating over the returned list: <pre>  {@code
    356    *
    357    *  List<E> l = Synchronized.list(new ArrayList<E>(), mutex);
    358    *  ...
    359    *  synchronized (mutex) {
    360    *    Iterator<E> i = l.iterator(); // Must be in synchronized block
    361    *    while (i.hasNext()) {
    362    *      foo(i.next());
    363    *    }
    364    *  }}</pre>
    365    *
    366    * Failure to follow this advice may result in non-deterministic behavior.
    367    *
    368    * <p>The returned list implements {@link RandomAccess} if the specified list
    369    * implements {@code RandomAccess}.
    370    *
    371    * @param list the list to be wrapped in a synchronized view
    372    * @return a synchronized view of the specified list
    373    */
    374   static <E> List<E> list(List<E> list, @Nullable Object mutex) {
    375     return (list instanceof RandomAccess)
    376         ? new SynchronizedRandomAccessList<E>(list, mutex)
    377         : new SynchronizedList<E>(list, mutex);
    378   }
    379 
    380   /** @see Synchronized#list */
    381   static class SynchronizedList<E> extends SynchronizedCollection<E>
    382       implements List<E> {
    383     public SynchronizedList(List<E> delegate, @Nullable Object mutex) {
    384       super(delegate, mutex);
    385     }
    386 
    387     @Override protected List<E> delegate() {
    388       return (List<E>) super.delegate();
    389     }
    390 
    391     public void add(int index, E element) {
    392       synchronized (mutex) {
    393         delegate().add(index, element);
    394       }
    395     }
    396 
    397     public boolean addAll(int index, Collection<? extends E> c) {
    398       synchronized (mutex) {
    399         return delegate().addAll(index, c);
    400       }
    401     }
    402 
    403     public E get(int index) {
    404       synchronized (mutex) {
    405         return delegate().get(index);
    406       }
    407     }
    408 
    409     public int indexOf(Object o) {
    410       synchronized (mutex) {
    411         return delegate().indexOf(o);
    412       }
    413     }
    414 
    415     public int lastIndexOf(Object o) {
    416       synchronized (mutex) {
    417         return delegate().lastIndexOf(o);
    418       }
    419     }
    420 
    421     public ListIterator<E> listIterator() {
    422       return delegate().listIterator(); // manually synchronized
    423     }
    424 
    425     public ListIterator<E> listIterator(int index) {
    426       return delegate().listIterator(index); // manually synchronized
    427     }
    428 
    429     public E remove(int index) {
    430       synchronized (mutex) {
    431         return delegate().remove(index);
    432       }
    433     }
    434 
    435     public E set(int index, E element) {
    436       synchronized (mutex) {
    437         return delegate().set(index, element);
    438       }
    439     }
    440 
    441     @GwtIncompatible("List.subList")
    442     public List<E> subList(int fromIndex, int toIndex) {
    443       synchronized (mutex) {
    444         return list(Platform.subList(delegate(), fromIndex, toIndex), mutex);
    445       }
    446     }
    447 
    448     @Override public boolean equals(Object o) {
    449       if (o == this) {
    450         return true;
    451       }
    452       synchronized (mutex) {
    453         return delegate().equals(o);
    454       }
    455     }
    456 
    457     @Override public int hashCode() {
    458       synchronized (mutex) {
    459         return delegate().hashCode();
    460       }
    461     }
    462 
    463     private static final long serialVersionUID = 0;
    464   }
    465 
    466   /** @see Synchronized#list */
    467   static class SynchronizedRandomAccessList<E> extends SynchronizedList<E>
    468       implements RandomAccess {
    469     public SynchronizedRandomAccessList(List<E> list, @Nullable Object mutex) {
    470       super(list, mutex);
    471     }
    472     private static final long serialVersionUID = 0;
    473   }
    474 
    475   /**
    476    * Returns a synchronized (thread-safe) multiset backed by the specified
    477    * multiset using the specified mutex. In order to guarantee serial access, it
    478    * is critical that <b>all</b> access to the backing multiset is accomplished
    479    * through the returned multiset.
    480    *
    481    * <p>It is imperative that the user manually synchronize on the specified
    482    * mutex when iterating over the returned multiset: <pre>  {@code
    483    *
    484    *  Multiset<E> s = Synchronized.multiset(
    485    *      HashMultiset.<E>create(), mutex);
    486    *  ...
    487    *  synchronized (mutex) {
    488    *    Iterator<E> i = s.iterator(); // Must be in synchronized block
    489    *    while (i.hasNext()) {
    490    *      foo(i.next());
    491    *    }
    492    *  }}</pre>
    493    *
    494    * Failure to follow this advice may result in non-deterministic behavior.
    495    *
    496    * @param multiset the multiset to be wrapped
    497    * @return a synchronized view of the specified multiset
    498    */
    499   private static <E> Multiset<E> multiset(
    500       Multiset<E> multiset, @Nullable Object mutex) {
    501     return new SynchronizedMultiset<E>(multiset, mutex);
    502   }
    503 
    504   /** @see Synchronized#multiset */
    505   static class SynchronizedMultiset<E> extends SynchronizedCollection<E>
    506       implements Multiset<E> {
    507     private transient Set<E> elementSet;
    508     private transient Set<Entry<E>> entrySet;
    509 
    510     public SynchronizedMultiset(Multiset<E> delegate, @Nullable Object mutex) {
    511       super(delegate, mutex);
    512     }
    513 
    514     @Override protected Multiset<E> delegate() {
    515       return (Multiset<E>) super.delegate();
    516     }
    517 
    518     public int count(Object o) {
    519       synchronized (mutex) {
    520         return delegate().count(o);
    521       }
    522     }
    523 
    524     public int add(E e, int n) {
    525       synchronized (mutex) {
    526         return delegate().add(e, n);
    527       }
    528     }
    529 
    530     public int remove(Object o, int n) {
    531       synchronized (mutex) {
    532         return delegate().remove(o, n);
    533       }
    534     }
    535 
    536     public int setCount(E element, int count) {
    537       synchronized (mutex) {
    538         return delegate().setCount(element, count);
    539       }
    540     }
    541 
    542     public boolean setCount(E element, int oldCount, int newCount) {
    543       synchronized (mutex) {
    544         return delegate().setCount(element, oldCount, newCount);
    545       }
    546     }
    547 
    548     public Set<E> elementSet() {
    549       synchronized (mutex) {
    550         if (elementSet == null) {
    551           elementSet = typePreservingSet(delegate().elementSet(), mutex);
    552         }
    553         return elementSet;
    554       }
    555     }
    556 
    557     public Set<Entry<E>> entrySet() {
    558       synchronized (mutex) {
    559         if (entrySet == null) {
    560           entrySet = typePreservingSet(delegate().entrySet(), mutex);
    561         }
    562         return entrySet;
    563       }
    564     }
    565 
    566     @Override public boolean equals(Object o) {
    567       if (o == this) {
    568         return true;
    569       }
    570       synchronized (mutex) {
    571         return delegate().equals(o);
    572       }
    573     }
    574 
    575     @Override public int hashCode() {
    576       synchronized (mutex) {
    577         return delegate().hashCode();
    578       }
    579     }
    580 
    581     private static final long serialVersionUID = 0;
    582   }
    583 
    584   /**
    585    * Returns a synchronized (thread-safe) multimap backed by the specified
    586    * multimap using the specified mutex. In order to guarantee serial access, it
    587    * is critical that <b>all</b> access to the backing multimap is accomplished
    588    * through the returned multimap.
    589    *
    590    * <p>It is imperative that the user manually synchronize on the specified
    591    * mutex when accessing any of the return multimap's collection views:
    592    * <pre>  {@code
    593    *
    594    *  Multimap<K, V> m = Synchronized.multimap(
    595    *      HashMultimap.create(), mutex);
    596    *  ...
    597    *  Set<K> s = m.keySet();  // Needn't be in synchronized block
    598    *  ...
    599    *  synchronized (mutex) {
    600    *    Iterator<K> i = s.iterator(); // Must be in synchronized block
    601    *    while (i.hasNext()) {
    602    *      foo(i.next());
    603    *    }
    604    *  }}</pre>
    605    *
    606    * Failure to follow this advice may result in non-deterministic behavior.
    607    *
    608    * @param multimap the multimap to be wrapped in a synchronized view
    609    * @return a synchronized view of the specified multimap
    610    */
    611   public static <K, V> Multimap<K, V> multimap(
    612       Multimap<K, V> multimap, @Nullable Object mutex) {
    613     return new SynchronizedMultimap<K, V>(multimap, mutex);
    614   }
    615 
    616   /** @see Synchronized#multimap */
    617   private static class SynchronizedMultimap<K, V> extends SynchronizedObject
    618       implements Multimap<K, V> {
    619     transient Set<K> keySet;
    620     transient Collection<V> valuesCollection;
    621     transient Collection<Map.Entry<K, V>> entries;
    622     transient Map<K, Collection<V>> asMap;
    623     transient Multiset<K> keys;
    624 
    625     @SuppressWarnings("unchecked")
    626     @Override protected Multimap<K, V> delegate() {
    627       return (Multimap<K, V>) super.delegate();
    628     }
    629 
    630     SynchronizedMultimap(Multimap<K, V> delegate, @Nullable Object mutex) {
    631       super(delegate, mutex);
    632     }
    633 
    634     public int size() {
    635       synchronized (mutex) {
    636         return delegate().size();
    637       }
    638     }
    639 
    640     public boolean isEmpty() {
    641       synchronized (mutex) {
    642         return delegate().isEmpty();
    643       }
    644     }
    645 
    646     public boolean containsKey(Object key) {
    647       synchronized (mutex) {
    648         return delegate().containsKey(key);
    649       }
    650     }
    651 
    652     public boolean containsValue(Object value) {
    653       synchronized (mutex) {
    654         return delegate().containsValue(value);
    655       }
    656     }
    657 
    658     public boolean containsEntry(Object key, Object value) {
    659       synchronized (mutex) {
    660         return delegate().containsEntry(key, value);
    661       }
    662     }
    663 
    664     public Collection<V> get(K key) {
    665       synchronized (mutex) {
    666         return typePreservingCollection(delegate().get(key), mutex);
    667       }
    668     }
    669 
    670     public boolean put(K key, V value) {
    671       synchronized (mutex) {
    672         return delegate().put(key, value);
    673       }
    674     }
    675 
    676     public boolean putAll(K key, Iterable<? extends V> values) {
    677       synchronized (mutex) {
    678         return delegate().putAll(key, values);
    679       }
    680     }
    681 
    682     public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
    683       synchronized (mutex) {
    684         return delegate().putAll(multimap);
    685       }
    686     }
    687 
    688     public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
    689       synchronized (mutex) {
    690         return delegate().replaceValues(key, values); // copy not synchronized
    691       }
    692     }
    693 
    694     public boolean remove(Object key, Object value) {
    695       synchronized (mutex) {
    696         return delegate().remove(key, value);
    697       }
    698     }
    699 
    700     public Collection<V> removeAll(Object key) {
    701       synchronized (mutex) {
    702         return delegate().removeAll(key); // copy not synchronized
    703       }
    704     }
    705 
    706     public void clear() {
    707       synchronized (mutex) {
    708         delegate().clear();
    709       }
    710     }
    711 
    712     public Set<K> keySet() {
    713       synchronized (mutex) {
    714         if (keySet == null) {
    715           keySet = typePreservingSet(delegate().keySet(), mutex);
    716         }
    717         return keySet;
    718       }
    719     }
    720 
    721     public Collection<V> values() {
    722       synchronized (mutex) {
    723         if (valuesCollection == null) {
    724           valuesCollection = collection(delegate().values(), mutex);
    725         }
    726         return valuesCollection;
    727       }
    728     }
    729 
    730     public Collection<Map.Entry<K, V>> entries() {
    731       synchronized (mutex) {
    732         if (entries == null) {
    733           entries = typePreservingCollection(delegate().entries(), mutex);
    734         }
    735         return entries;
    736       }
    737     }
    738 
    739     public Map<K, Collection<V>> asMap() {
    740       synchronized (mutex) {
    741         if (asMap == null) {
    742           asMap = new SynchronizedAsMap<K, V>(delegate().asMap(), mutex);
    743         }
    744         return asMap;
    745       }
    746     }
    747 
    748     public Multiset<K> keys() {
    749       synchronized (mutex) {
    750         if (keys == null) {
    751           keys = multiset(delegate().keys(), mutex);
    752         }
    753         return keys;
    754       }
    755     }
    756 
    757     @Override public boolean equals(Object o) {
    758       if (o == this) {
    759         return true;
    760       }
    761       synchronized (mutex) {
    762         return delegate().equals(o);
    763       }
    764     }
    765 
    766     @Override public int hashCode() {
    767       synchronized (mutex) {
    768         return delegate().hashCode();
    769       }
    770     }
    771 
    772     private static final long serialVersionUID = 0;
    773   }
    774 
    775   /**
    776    * Returns a synchronized (thread-safe) list multimap backed by the specified
    777    * multimap using the specified mutex.
    778    *
    779    * <p>You must follow the warnings described for {@link #multimap}.
    780    *
    781    * @param multimap the multimap to be wrapped in a synchronized view
    782    * @return a synchronized view of the specified multimap
    783    */
    784   public static <K, V> ListMultimap<K, V> listMultimap(
    785       ListMultimap<K, V> multimap, @Nullable Object mutex) {
    786     return new SynchronizedListMultimap<K, V>(multimap, mutex);
    787   }
    788 
    789   /** @see Synchronized#listMultimap */
    790   private static class SynchronizedListMultimap<K, V>
    791       extends SynchronizedMultimap<K, V> implements ListMultimap<K, V> {
    792     SynchronizedListMultimap(
    793         ListMultimap<K, V> delegate, @Nullable Object mutex) {
    794       super(delegate, mutex);
    795     }
    796     @Override protected ListMultimap<K, V> delegate() {
    797       return (ListMultimap<K, V>) super.delegate();
    798     }
    799     @Override public List<V> get(K key) {
    800       synchronized (mutex) {
    801         return list(delegate().get(key), mutex);
    802       }
    803     }
    804     @Override public List<V> removeAll(Object key) {
    805       synchronized (mutex) {
    806         return delegate().removeAll(key); // copy not synchronized
    807       }
    808     }
    809     @Override public List<V> replaceValues(
    810         K key, Iterable<? extends V> values) {
    811       synchronized (mutex) {
    812         return delegate().replaceValues(key, values); // copy not synchronized
    813       }
    814     }
    815     private static final long serialVersionUID = 0;
    816   }
    817 
    818   /**
    819    * Returns a synchronized (thread-safe) set multimap backed by the specified
    820    * multimap using the specified mutex.
    821    *
    822    * <p>You must follow the warnings described for {@link #multimap}.
    823    *
    824    * @param multimap the multimap to be wrapped in a synchronized view
    825    * @return a synchronized view of the specified multimap
    826    */
    827   public static <K, V> SetMultimap<K, V> setMultimap(
    828       SetMultimap<K, V> multimap, @Nullable Object mutex) {
    829     return new SynchronizedSetMultimap<K, V>(multimap, mutex);
    830   }
    831 
    832   /** @see Synchronized#setMultimap */
    833   private static class SynchronizedSetMultimap<K, V>
    834       extends SynchronizedMultimap<K, V> implements SetMultimap<K, V> {
    835     transient Set<Map.Entry<K, V>> entrySet;
    836     SynchronizedSetMultimap(
    837         SetMultimap<K, V> delegate, @Nullable Object mutex) {
    838       super(delegate, mutex);
    839     }
    840     @Override protected SetMultimap<K, V> delegate() {
    841       return (SetMultimap<K, V>) super.delegate();
    842     }
    843     @Override public Set<V> get(K key) {
    844       synchronized (mutex) {
    845         return set(delegate().get(key), mutex);
    846       }
    847     }
    848     @Override public Set<V> removeAll(Object key) {
    849       synchronized (mutex) {
    850         return delegate().removeAll(key); // copy not synchronized
    851       }
    852     }
    853     @Override public Set<V> replaceValues(
    854         K key, Iterable<? extends V> values) {
    855       synchronized (mutex) {
    856         return delegate().replaceValues(key, values); // copy not synchronized
    857       }
    858     }
    859     @Override public Set<Map.Entry<K, V>> entries() {
    860       synchronized (mutex) {
    861         if (entrySet == null) {
    862           entrySet = set(delegate().entries(), mutex);
    863         }
    864         return entrySet;
    865       }
    866     }
    867     private static final long serialVersionUID = 0;
    868   }
    869 
    870   /**
    871    * Returns a synchronized (thread-safe) sorted set multimap backed by the
    872    * specified multimap using the specified mutex.
    873    *
    874    * <p>You must follow the warnings described for {@link #multimap}.
    875    *
    876    * @param multimap the multimap to be wrapped in a synchronized view
    877    * @return a synchronized view of the specified multimap
    878    */
    879   public static <K, V> SortedSetMultimap<K, V> sortedSetMultimap(
    880       SortedSetMultimap<K, V> multimap, @Nullable Object mutex) {
    881     return new SynchronizedSortedSetMultimap<K, V>(multimap, mutex);
    882   }
    883 
    884   /** @see Synchronized#sortedSetMultimap */
    885   private static class SynchronizedSortedSetMultimap<K, V>
    886       extends SynchronizedSetMultimap<K, V> implements SortedSetMultimap<K, V> {
    887     SynchronizedSortedSetMultimap(
    888         SortedSetMultimap<K, V> delegate, @Nullable Object mutex) {
    889       super(delegate, mutex);
    890     }
    891     @Override protected SortedSetMultimap<K, V> delegate() {
    892       return (SortedSetMultimap<K, V>) super.delegate();
    893     }
    894     @Override public SortedSet<V> get(K key) {
    895       synchronized (mutex) {
    896         return sortedSet(delegate().get(key), mutex);
    897       }
    898     }
    899     @Override public SortedSet<V> removeAll(Object key) {
    900       synchronized (mutex) {
    901         return delegate().removeAll(key); // copy not synchronized
    902       }
    903     }
    904     @Override public SortedSet<V> replaceValues(
    905         K key, Iterable<? extends V> values) {
    906       synchronized (mutex) {
    907         return delegate().replaceValues(key, values); // copy not synchronized
    908       }
    909     }
    910     public Comparator<? super V> valueComparator() {
    911       synchronized (mutex) {
    912         return delegate().valueComparator();
    913       }
    914     }
    915     private static final long serialVersionUID = 0;
    916   }
    917 
    918   /**
    919    * Returns a synchronized (thread-safe) collection backed by the specified
    920    * collection using the specified mutex. In order to guarantee serial access,
    921    * it is critical that <b>all</b> access to the backing collection is
    922    * accomplished through the returned collection.
    923    *
    924    * <p>It is imperative that the user manually synchronize on the specified
    925    * mutex when iterating over the returned collection: <pre>  {@code
    926    *
    927    *  Collection<E> s = Synchronized.typePreservingCollection(
    928    *      new HashSet<E>(), mutex);
    929    *  ...
    930    *  synchronized (mutex) {
    931    *    Iterator<E> i = s.iterator(); // Must be in synchronized block
    932    *    while (i.hasNext()) {
    933    *      foo(i.next());
    934    *    }
    935    *  }}</pre>
    936    *
    937    * Failure to follow this advice may result in non-deterministic behavior.
    938    *
    939    * <p>If the specified collection is a {@code SortedSet}, {@code Set} or
    940    * {@code List}, this method will behave identically to {@link #sortedSet},
    941    * {@link #set} or {@link #list} respectively, in that order of specificity.
    942    *
    943    * @param collection the collection to be wrapped in a synchronized view
    944    * @return a synchronized view of the specified collection
    945    */
    946   private static <E> Collection<E> typePreservingCollection(
    947       Collection<E> collection, @Nullable Object mutex) {
    948     if (collection instanceof SortedSet) {
    949       return sortedSet((SortedSet<E>) collection, mutex);
    950     } else if (collection instanceof Set) {
    951       return set((Set<E>) collection, mutex);
    952     } else if (collection instanceof List) {
    953       return list((List<E>) collection, mutex);
    954     } else {
    955       return collection(collection, mutex);
    956     }
    957   }
    958 
    959   /**
    960    * Returns a synchronized (thread-safe) set backed by the specified set using
    961    * the specified mutex. In order to guarantee serial access, it is critical
    962    * that <b>all</b> access to the backing collection is accomplished through
    963    * the returned collection.
    964    *
    965    * <p>It is imperative that the user manually synchronize on the specified
    966    * mutex when iterating over the returned collection: <pre>  {@code
    967    *
    968    *  Set<E> s = Synchronized.typePreservingSet(
    969    *      new HashSet<E>(), mutex);
    970    *  ...
    971    *  synchronized (mutex) {
    972    *    Iterator<E> i = s.iterator(); // Must be in synchronized block
    973    *    while (i.hasNext()) {
    974    *      foo(i.next());
    975    *    }
    976    *  }}</pre>
    977    *
    978    * Failure to follow this advice may result in non-deterministic behavior.
    979    *
    980    * <p>If the specified collection is a {@code SortedSet} this method will
    981    * behave identically to {@link #sortedSet}.
    982    *
    983    * @param set the set to be wrapped in a synchronized view
    984    * @return a synchronized view of the specified set
    985    */
    986   public static <E> Set<E> typePreservingSet(
    987       Set<E> set, @Nullable Object mutex) {
    988     if (set instanceof SortedSet) {
    989       return sortedSet((SortedSet<E>) set, mutex);
    990     } else {
    991       return set(set, mutex);
    992     }
    993   }
    994 
    995   /** @see Synchronized#multimap */
    996   static class SynchronizedAsMapEntries<K, V>
    997       extends SynchronizedSet<Map.Entry<K, Collection<V>>> {
    998     public SynchronizedAsMapEntries(
    999         Set<Map.Entry<K, Collection<V>>> delegate, @Nullable Object mutex) {
   1000       super(delegate, mutex);
   1001     }
   1002 
   1003     @Override public Iterator<Map.Entry<K, Collection<V>>> iterator() {
   1004       // Must be manually synchronized.
   1005       final Iterator<Map.Entry<K, Collection<V>>> iterator = super.iterator();
   1006       return new ForwardingIterator<Map.Entry<K, Collection<V>>>() {
   1007         @Override protected Iterator<Map.Entry<K, Collection<V>>> delegate() {
   1008           return iterator;
   1009         }
   1010 
   1011         @Override public Map.Entry<K, Collection<V>> next() {
   1012           final Map.Entry<K, Collection<V>> entry = iterator.next();
   1013           return new ForwardingMapEntry<K, Collection<V>>() {
   1014             @Override protected Map.Entry<K, Collection<V>> delegate() {
   1015               return entry;
   1016             }
   1017             @Override public Collection<V> getValue() {
   1018               return typePreservingCollection(entry.getValue(), mutex);
   1019             }
   1020           };
   1021         }
   1022       };
   1023     }
   1024 
   1025     // See Collections.CheckedMap.CheckedEntrySet for details on attacks.
   1026 
   1027     @Override public Object[] toArray() {
   1028       synchronized (mutex) {
   1029         return ObjectArrays.toArrayImpl(delegate());
   1030       }
   1031     }
   1032     @Override public <T> T[] toArray(T[] array) {
   1033       synchronized (mutex) {
   1034         return ObjectArrays.toArrayImpl(delegate(), array);
   1035       }
   1036     }
   1037     @Override public boolean contains(Object o) {
   1038       synchronized (mutex) {
   1039         return Maps.containsEntryImpl(delegate(), o);
   1040       }
   1041     }
   1042     @Override public boolean containsAll(Collection<?> c) {
   1043       synchronized (mutex) {
   1044         return Collections2.containsAll(delegate(), c);
   1045       }
   1046     }
   1047     @Override public boolean equals(Object o) {
   1048       if (o == this) {
   1049         return true;
   1050       }
   1051       synchronized (mutex) {
   1052         return Collections2.setEquals(delegate(), o);
   1053       }
   1054     }
   1055     @Override public boolean remove(Object o) {
   1056       synchronized (mutex) {
   1057         return Maps.removeEntryImpl(delegate(), o);
   1058       }
   1059     }
   1060     @Override public boolean removeAll(Collection<?> c) {
   1061       synchronized (mutex) {
   1062         return Iterators.removeAll(delegate().iterator(), c);
   1063       }
   1064     }
   1065     @Override public boolean retainAll(Collection<?> c) {
   1066       synchronized (mutex) {
   1067         return Iterators.retainAll(delegate().iterator(), c);
   1068       }
   1069     }
   1070 
   1071     private static final long serialVersionUID = 0;
   1072   }
   1073 
   1074   /**
   1075    * Returns a synchronized (thread-safe) map backed by the specified map using
   1076    * the specified mutex. In order to guarantee serial access, it is critical
   1077    * that <b>all</b> access to the backing map is accomplished through the
   1078    * returned map.
   1079    *
   1080    * <p>It is imperative that the user manually synchronize on the specified
   1081    * mutex when accessing any of the return map's collection views:
   1082    * <pre>  {@code
   1083    *
   1084    *  Map<K, V> m = Synchronized.map(
   1085    *      new HashMap<K, V>(), mutex);
   1086    *  ...
   1087    *  Set<K> s = m.keySet();  // Needn't be in synchronized block
   1088    *  ...
   1089    *  synchronized (mutex) {
   1090    *    Iterator<K> i = s.iterator(); // Must be in synchronized block
   1091    *    while (i.hasNext()) {
   1092    *      foo(i.next());
   1093    *    }
   1094    *  }}</pre>
   1095    *
   1096    * Failure to follow this advice may result in non-deterministic behavior.
   1097    *
   1098    * @param map the map to be wrapped in a synchronized view
   1099    * @return a synchronized view of the specified map
   1100    */
   1101   public static <K, V> Map<K, V> map(Map<K, V> map, @Nullable Object mutex) {
   1102     return new SynchronizedMap<K, V>(map, mutex);
   1103   }
   1104 
   1105   /** @see Synchronized#map */
   1106   static class SynchronizedMap<K, V> extends SynchronizedObject
   1107       implements Map<K, V> {
   1108     private transient Set<K> keySet;
   1109     private transient Collection<V> values;
   1110     private transient Set<Map.Entry<K, V>> entrySet;
   1111 
   1112     public SynchronizedMap(Map<K, V> delegate, @Nullable Object mutex) {
   1113       super(delegate, mutex);
   1114     }
   1115 
   1116     @SuppressWarnings("unchecked")
   1117     @Override protected Map<K, V> delegate() {
   1118       return (Map<K, V>) super.delegate();
   1119     }
   1120 
   1121     public void clear() {
   1122       synchronized (mutex) {
   1123         delegate().clear();
   1124       }
   1125     }
   1126 
   1127     public boolean containsKey(Object key) {
   1128       synchronized (mutex) {
   1129         return delegate().containsKey(key);
   1130       }
   1131     }
   1132 
   1133     public boolean containsValue(Object value) {
   1134       synchronized (mutex) {
   1135         return delegate().containsValue(value);
   1136       }
   1137     }
   1138 
   1139     public Set<Map.Entry<K, V>> entrySet() {
   1140       synchronized (mutex) {
   1141         if (entrySet == null) {
   1142           entrySet = set(delegate().entrySet(), mutex);
   1143         }
   1144         return entrySet;
   1145       }
   1146     }
   1147 
   1148     public V get(Object key) {
   1149       synchronized (mutex) {
   1150         return delegate().get(key);
   1151       }
   1152     }
   1153 
   1154     public boolean isEmpty() {
   1155       synchronized (mutex) {
   1156         return delegate().isEmpty();
   1157       }
   1158     }
   1159 
   1160     public Set<K> keySet() {
   1161       synchronized (mutex) {
   1162         if (keySet == null) {
   1163           keySet = set(delegate().keySet(), mutex);
   1164         }
   1165         return keySet;
   1166       }
   1167     }
   1168 
   1169     public V put(K key, V value) {
   1170       synchronized (mutex) {
   1171         return delegate().put(key, value);
   1172       }
   1173     }
   1174 
   1175     public void putAll(Map<? extends K, ? extends V> map) {
   1176       synchronized (mutex) {
   1177         delegate().putAll(map);
   1178       }
   1179     }
   1180 
   1181     public V remove(Object key) {
   1182       synchronized (mutex) {
   1183         return delegate().remove(key);
   1184       }
   1185     }
   1186 
   1187     public int size() {
   1188       synchronized (mutex) {
   1189         return delegate().size();
   1190       }
   1191     }
   1192 
   1193     public Collection<V> values() {
   1194       synchronized (mutex) {
   1195         if (values == null) {
   1196           values = collection(delegate().values(), mutex);
   1197         }
   1198         return values;
   1199       }
   1200     }
   1201 
   1202     @Override public boolean equals(Object o) {
   1203       if (o == this) {
   1204         return true;
   1205       }
   1206       synchronized (mutex) {
   1207         return delegate().equals(o);
   1208       }
   1209     }
   1210 
   1211     @Override public int hashCode() {
   1212       synchronized (mutex) {
   1213         return delegate().hashCode();
   1214       }
   1215     }
   1216 
   1217     private static final long serialVersionUID = 0;
   1218   }
   1219 
   1220   /**
   1221    * Returns a synchronized (thread-safe) bimap backed by the specified bimap
   1222    * using the specified mutex. In order to guarantee serial access, it is
   1223    * critical that <b>all</b> access to the backing bimap is accomplished
   1224    * through the returned bimap.
   1225    *
   1226    * <p>It is imperative that the user manually synchronize on the specified
   1227    * mutex when accessing any of the return bimap's collection views:
   1228    * <pre>  {@code
   1229    *
   1230    *  BiMap<K, V> m = Synchronized.biMap(
   1231    *      HashBiMap.<K, V>create(), mutex);
   1232    *  ...
   1233    *  Set<K> s = m.keySet();  // Needn't be in synchronized block
   1234    *  ...
   1235    *  synchronized (mutex) {
   1236    *    Iterator<K> i = s.iterator(); // Must be in synchronized block
   1237    *    while (i.hasNext()) {
   1238    *      foo(i.next());
   1239    *    }
   1240    *  }}</pre>
   1241    *
   1242    * Failure to follow this advice may result in non-deterministic behavior.
   1243    *
   1244    * @param bimap the bimap to be wrapped in a synchronized view
   1245    * @return a synchronized view of the specified bimap
   1246    */
   1247   public static <K, V> BiMap<K, V> biMap(
   1248       BiMap<K, V> bimap, @Nullable Object mutex) {
   1249     return new SynchronizedBiMap<K, V>(bimap, mutex, null);
   1250   }
   1251 
   1252   /** @see Synchronized#biMap */
   1253   static class SynchronizedBiMap<K, V> extends SynchronizedMap<K, V>
   1254       implements BiMap<K, V>, Serializable {
   1255     private transient Set<V> valueSet;
   1256     private transient BiMap<V, K> inverse;
   1257 
   1258     public SynchronizedBiMap(
   1259         BiMap<K, V> delegate, @Nullable Object mutex,
   1260         @Nullable BiMap<V, K> inverse) {
   1261       super(delegate, mutex);
   1262       this.inverse = inverse;
   1263     }
   1264 
   1265     @Override protected BiMap<K, V> delegate() {
   1266       return (BiMap<K, V>) super.delegate();
   1267     }
   1268 
   1269     @Override public Set<V> values() {
   1270       synchronized (mutex) {
   1271         if (valueSet == null) {
   1272           valueSet = set(delegate().values(), mutex);
   1273         }
   1274         return valueSet;
   1275       }
   1276     }
   1277 
   1278     public V forcePut(K key, V value) {
   1279       synchronized (mutex) {
   1280         return delegate().forcePut(key, value);
   1281       }
   1282     }
   1283 
   1284     public BiMap<V, K> inverse() {
   1285       synchronized (mutex) {
   1286         if (inverse == null) {
   1287           inverse
   1288               = new SynchronizedBiMap<V, K>(delegate().inverse(), mutex, this);
   1289         }
   1290         return inverse;
   1291       }
   1292     }
   1293 
   1294     private static final long serialVersionUID = 0;
   1295   }
   1296 
   1297   /** @see SynchronizedMultimap#asMap */
   1298   static class SynchronizedAsMap<K, V>
   1299       extends SynchronizedMap<K, Collection<V>> {
   1300     private transient Set<Map.Entry<K, Collection<V>>> asMapEntrySet;
   1301     private transient Collection<Collection<V>> asMapValues;
   1302 
   1303     public SynchronizedAsMap(
   1304         Map<K, Collection<V>> delegate, @Nullable Object mutex) {
   1305       super(delegate, mutex);
   1306     }
   1307 
   1308     @Override public Collection<V> get(Object key) {
   1309       synchronized (mutex) {
   1310         Collection<V> collection = super.get(key);
   1311         return (collection == null) ? null
   1312             : typePreservingCollection(collection, mutex);
   1313       }
   1314     }
   1315 
   1316     @Override public Set<Map.Entry<K, Collection<V>>> entrySet() {
   1317       synchronized (mutex) {
   1318         if (asMapEntrySet == null) {
   1319           asMapEntrySet = new SynchronizedAsMapEntries<K, V>(
   1320               delegate().entrySet(), mutex);
   1321         }
   1322         return asMapEntrySet;
   1323       }
   1324     }
   1325 
   1326     @Override public Collection<Collection<V>> values() {
   1327       synchronized (mutex) {
   1328         if (asMapValues == null) {
   1329           asMapValues
   1330               = new SynchronizedAsMapValues<V>(delegate().values(), mutex);
   1331         }
   1332         return asMapValues;
   1333       }
   1334     }
   1335 
   1336     @Override public boolean containsValue(Object o) {
   1337       // values() and its contains() method are both synchronized.
   1338       return values().contains(o);
   1339     }
   1340 
   1341     private static final long serialVersionUID = 0;
   1342   }
   1343 
   1344   /** @see SynchronizedMultimap#asMap */
   1345   static class SynchronizedAsMapValues<V>
   1346       extends SynchronizedCollection<Collection<V>> {
   1347     SynchronizedAsMapValues(
   1348         Collection<Collection<V>> delegate, @Nullable Object mutex) {
   1349       super(delegate, mutex);
   1350     }
   1351 
   1352     @Override public Iterator<Collection<V>> iterator() {
   1353       // Must be manually synchronized.
   1354       final Iterator<Collection<V>> iterator = super.iterator();
   1355       return new ForwardingIterator<Collection<V>>() {
   1356         @Override protected Iterator<Collection<V>> delegate() {
   1357           return iterator;
   1358         }
   1359         @Override public Collection<V> next() {
   1360           return typePreservingCollection(iterator.next(), mutex);
   1361         }
   1362       };
   1363     }
   1364 
   1365     private static final long serialVersionUID = 0;
   1366   }
   1367 }
   1368