View Javadoc
1   /*
2    * Copyright (C) 2007 The Guava Authors
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 static com.google.common.base.Preconditions.checkNotNull;
20  
21  import com.google.common.annotations.GwtCompatible;
22  import com.google.common.annotations.GwtIncompatible;
23  import com.google.common.annotations.VisibleForTesting;
24  import com.google.j2objc.annotations.RetainedWith;
25  import java.io.IOException;
26  import java.io.ObjectOutputStream;
27  import java.io.Serializable;
28  import java.util.Collection;
29  import java.util.Comparator;
30  import java.util.Deque;
31  import java.util.Iterator;
32  import java.util.List;
33  import java.util.ListIterator;
34  import java.util.Map;
35  import java.util.Map.Entry;
36  import java.util.NavigableMap;
37  import java.util.NavigableSet;
38  import java.util.Queue;
39  import java.util.RandomAccess;
40  import java.util.Set;
41  import java.util.SortedMap;
42  import java.util.SortedSet;
43  import java.util.Spliterator;
44  import java.util.function.BiConsumer;
45  import java.util.function.BiFunction;
46  import java.util.function.Consumer;
47  import java.util.function.Function;
48  import java.util.function.Predicate;
49  import java.util.function.UnaryOperator;
50  import java.util.stream.Stream;
51  import javax.annotation.Nullable;
52  
53  /**
54   * Synchronized collection views. The returned synchronized collection views are
55   * serializable if the backing collection and the mutex are serializable.
56   *
57   * <p>If {@code null} is passed as the {@code mutex} parameter to any of this
58   * class's top-level methods or inner class constructors, the created object
59   * uses itself as the synchronization mutex.
60   *
61   * <p>This class should be used by other collection classes only.
62   *
63   * @author Mike Bostock
64   * @author Jared Levy
65   */
66  @GwtCompatible(emulated = true)
67  final class Synchronized {
68    private Synchronized() {}
69  
70    static class SynchronizedObject implements Serializable {
71      final Object delegate;
72      final Object mutex;
73  
74      SynchronizedObject(Object delegate, @Nullable Object mutex) {
75        this.delegate = checkNotNull(delegate);
76        this.mutex = (mutex == null) ? this : mutex;
77      }
78  
79      Object delegate() {
80        return delegate;
81      }
82  
83      // No equals and hashCode; see ForwardingObject for details.
84  
85      @Override
86      public String toString() {
87        synchronized (mutex) {
88          return delegate.toString();
89        }
90      }
91  
92      // Serialization invokes writeObject only when it's private.
93      // The SynchronizedObject subclasses don't need a writeObject method since
94      // they don't contain any non-transient member variables, while the
95      // following writeObject() handles the SynchronizedObject members.
96  
97      @GwtIncompatible // java.io.ObjectOutputStream
98      private void writeObject(ObjectOutputStream stream) throws IOException {
99        synchronized (mutex) {
100         stream.defaultWriteObject();
101       }
102     }
103 
104     @GwtIncompatible // not needed in emulated source
105     private static final long serialVersionUID = 0;
106   }
107 
108   private static <E> Collection<E> collection(Collection<E> collection, @Nullable Object mutex) {
109     return new SynchronizedCollection<E>(collection, mutex);
110   }
111 
112   @VisibleForTesting
113   static class SynchronizedCollection<E> extends SynchronizedObject implements Collection<E> {
114     private SynchronizedCollection(Collection<E> delegate, @Nullable Object mutex) {
115       super(delegate, mutex);
116     }
117 
118     @SuppressWarnings("unchecked")
119     @Override
120     Collection<E> delegate() {
121       return (Collection<E>) super.delegate();
122     }
123 
124     @Override
125     public boolean add(E e) {
126       synchronized (mutex) {
127         return delegate().add(e);
128       }
129     }
130 
131     @Override
132     public boolean addAll(Collection<? extends E> c) {
133       synchronized (mutex) {
134         return delegate().addAll(c);
135       }
136     }
137 
138     @Override
139     public void clear() {
140       synchronized (mutex) {
141         delegate().clear();
142       }
143     }
144 
145     @Override
146     public boolean contains(Object o) {
147       synchronized (mutex) {
148         return delegate().contains(o);
149       }
150     }
151 
152     @Override
153     public boolean containsAll(Collection<?> c) {
154       synchronized (mutex) {
155         return delegate().containsAll(c);
156       }
157     }
158 
159     @Override
160     public boolean isEmpty() {
161       synchronized (mutex) {
162         return delegate().isEmpty();
163       }
164     }
165 
166     @Override
167     public Iterator<E> iterator() {
168       return delegate().iterator(); // manually synchronized
169     }
170 
171     @Override
172     public Spliterator<E> spliterator() {
173       synchronized (mutex) {
174         return delegate().spliterator();
175       }
176     }
177 
178     @Override
179     public Stream<E> stream() {
180       synchronized (mutex) {
181         return delegate().stream();
182       }
183     }
184 
185     @Override
186     public Stream<E> parallelStream() {
187       synchronized (mutex) {
188         return delegate().parallelStream();
189       }
190     }
191 
192     @Override
193     public void forEach(Consumer<? super E> action) {
194       synchronized (mutex) {
195         delegate().forEach(action);
196       }
197     }
198 
199     @Override
200     public boolean remove(Object o) {
201       synchronized (mutex) {
202         return delegate().remove(o);
203       }
204     }
205 
206     @Override
207     public boolean removeAll(Collection<?> c) {
208       synchronized (mutex) {
209         return delegate().removeAll(c);
210       }
211     }
212 
213     @Override
214     public boolean retainAll(Collection<?> c) {
215       synchronized (mutex) {
216         return delegate().retainAll(c);
217       }
218     }
219 
220     @Override
221     public boolean removeIf(Predicate<? super E> filter) {
222       synchronized (mutex) {
223         return delegate().removeIf(filter);
224       }
225     }
226 
227     @Override
228     public int size() {
229       synchronized (mutex) {
230         return delegate().size();
231       }
232     }
233 
234     @Override
235     public Object[] toArray() {
236       synchronized (mutex) {
237         return delegate().toArray();
238       }
239     }
240 
241     @Override
242     public <T> T[] toArray(T[] a) {
243       synchronized (mutex) {
244         return delegate().toArray(a);
245       }
246     }
247 
248     private static final long serialVersionUID = 0;
249   }
250 
251   @VisibleForTesting
252   static <E> Set<E> set(Set<E> set, @Nullable Object mutex) {
253     return new SynchronizedSet<E>(set, mutex);
254   }
255 
256   static class SynchronizedSet<E> extends SynchronizedCollection<E> implements Set<E> {
257 
258     SynchronizedSet(Set<E> delegate, @Nullable Object mutex) {
259       super(delegate, mutex);
260     }
261 
262     @Override
263     Set<E> delegate() {
264       return (Set<E>) super.delegate();
265     }
266 
267     @Override
268     public boolean equals(Object o) {
269       if (o == this) {
270         return true;
271       }
272       synchronized (mutex) {
273         return delegate().equals(o);
274       }
275     }
276 
277     @Override
278     public int hashCode() {
279       synchronized (mutex) {
280         return delegate().hashCode();
281       }
282     }
283 
284     private static final long serialVersionUID = 0;
285   }
286 
287   private static <E> SortedSet<E> sortedSet(SortedSet<E> set, @Nullable Object mutex) {
288     return new SynchronizedSortedSet<E>(set, mutex);
289   }
290 
291   static class SynchronizedSortedSet<E> extends SynchronizedSet<E> implements SortedSet<E> {
292     SynchronizedSortedSet(SortedSet<E> delegate, @Nullable Object mutex) {
293       super(delegate, mutex);
294     }
295 
296     @Override
297     SortedSet<E> delegate() {
298       return (SortedSet<E>) super.delegate();
299     }
300 
301     @Override
302     public Comparator<? super E> comparator() {
303       synchronized (mutex) {
304         return delegate().comparator();
305       }
306     }
307 
308     @Override
309     public SortedSet<E> subSet(E fromElement, E toElement) {
310       synchronized (mutex) {
311         return sortedSet(delegate().subSet(fromElement, toElement), mutex);
312       }
313     }
314 
315     @Override
316     public SortedSet<E> headSet(E toElement) {
317       synchronized (mutex) {
318         return sortedSet(delegate().headSet(toElement), mutex);
319       }
320     }
321 
322     @Override
323     public SortedSet<E> tailSet(E fromElement) {
324       synchronized (mutex) {
325         return sortedSet(delegate().tailSet(fromElement), mutex);
326       }
327     }
328 
329     @Override
330     public E first() {
331       synchronized (mutex) {
332         return delegate().first();
333       }
334     }
335 
336     @Override
337     public E last() {
338       synchronized (mutex) {
339         return delegate().last();
340       }
341     }
342 
343     private static final long serialVersionUID = 0;
344   }
345 
346   private static <E> List<E> list(List<E> list, @Nullable Object mutex) {
347     return (list instanceof RandomAccess)
348         ? new SynchronizedRandomAccessList<E>(list, mutex)
349         : new SynchronizedList<E>(list, mutex);
350   }
351 
352   private static class SynchronizedList<E> extends SynchronizedCollection<E> implements List<E> {
353     SynchronizedList(List<E> delegate, @Nullable Object mutex) {
354       super(delegate, mutex);
355     }
356 
357     @Override
358     List<E> delegate() {
359       return (List<E>) super.delegate();
360     }
361 
362     @Override
363     public void add(int index, E element) {
364       synchronized (mutex) {
365         delegate().add(index, element);
366       }
367     }
368 
369     @Override
370     public boolean addAll(int index, Collection<? extends E> c) {
371       synchronized (mutex) {
372         return delegate().addAll(index, c);
373       }
374     }
375 
376     @Override
377     public E get(int index) {
378       synchronized (mutex) {
379         return delegate().get(index);
380       }
381     }
382 
383     @Override
384     public int indexOf(Object o) {
385       synchronized (mutex) {
386         return delegate().indexOf(o);
387       }
388     }
389 
390     @Override
391     public int lastIndexOf(Object o) {
392       synchronized (mutex) {
393         return delegate().lastIndexOf(o);
394       }
395     }
396 
397     @Override
398     public ListIterator<E> listIterator() {
399       return delegate().listIterator(); // manually synchronized
400     }
401 
402     @Override
403     public ListIterator<E> listIterator(int index) {
404       return delegate().listIterator(index); // manually synchronized
405     }
406 
407     @Override
408     public E remove(int index) {
409       synchronized (mutex) {
410         return delegate().remove(index);
411       }
412     }
413 
414     @Override
415     public E set(int index, E element) {
416       synchronized (mutex) {
417         return delegate().set(index, element);
418       }
419     }
420 
421     @Override
422     public void replaceAll(UnaryOperator<E> operator) {
423       synchronized (mutex) {
424         delegate().replaceAll(operator);
425       }
426     }
427 
428     @Override
429     public void sort(Comparator<? super E> c) {
430       synchronized (mutex) {
431         delegate().sort(c);
432       }
433     }
434 
435     @Override
436     public List<E> subList(int fromIndex, int toIndex) {
437       synchronized (mutex) {
438         return list(delegate().subList(fromIndex, toIndex), mutex);
439       }
440     }
441 
442     @Override
443     public boolean equals(Object o) {
444       if (o == this) {
445         return true;
446       }
447       synchronized (mutex) {
448         return delegate().equals(o);
449       }
450     }
451 
452     @Override
453     public int hashCode() {
454       synchronized (mutex) {
455         return delegate().hashCode();
456       }
457     }
458 
459     private static final long serialVersionUID = 0;
460   }
461 
462   private static class SynchronizedRandomAccessList<E> extends SynchronizedList<E>
463       implements RandomAccess {
464     SynchronizedRandomAccessList(List<E> list, @Nullable Object mutex) {
465       super(list, mutex);
466     }
467 
468     private static final long serialVersionUID = 0;
469   }
470 
471   static <E> Multiset<E> multiset(Multiset<E> multiset, @Nullable Object mutex) {
472     if (multiset instanceof SynchronizedMultiset || multiset instanceof ImmutableMultiset) {
473       return multiset;
474     }
475     return new SynchronizedMultiset<E>(multiset, mutex);
476   }
477 
478   private static class SynchronizedMultiset<E> extends SynchronizedCollection<E>
479       implements Multiset<E> {
480     transient Set<E> elementSet;
481     transient Set<Entry<E>> entrySet;
482 
483     SynchronizedMultiset(Multiset<E> delegate, @Nullable Object mutex) {
484       super(delegate, mutex);
485     }
486 
487     @Override
488     Multiset<E> delegate() {
489       return (Multiset<E>) super.delegate();
490     }
491 
492     @Override
493     public int count(Object o) {
494       synchronized (mutex) {
495         return delegate().count(o);
496       }
497     }
498 
499     @Override
500     public int add(E e, int n) {
501       synchronized (mutex) {
502         return delegate().add(e, n);
503       }
504     }
505 
506     @Override
507     public int remove(Object o, int n) {
508       synchronized (mutex) {
509         return delegate().remove(o, n);
510       }
511     }
512 
513     @Override
514     public int setCount(E element, int count) {
515       synchronized (mutex) {
516         return delegate().setCount(element, count);
517       }
518     }
519 
520     @Override
521     public boolean setCount(E element, int oldCount, int newCount) {
522       synchronized (mutex) {
523         return delegate().setCount(element, oldCount, newCount);
524       }
525     }
526 
527     @Override
528     public Set<E> elementSet() {
529       synchronized (mutex) {
530         if (elementSet == null) {
531           elementSet = typePreservingSet(delegate().elementSet(), mutex);
532         }
533         return elementSet;
534       }
535     }
536 
537     @Override
538     public Set<Entry<E>> entrySet() {
539       synchronized (mutex) {
540         if (entrySet == null) {
541           entrySet = typePreservingSet(delegate().entrySet(), mutex);
542         }
543         return entrySet;
544       }
545     }
546 
547     @Override
548     public boolean equals(Object o) {
549       if (o == this) {
550         return true;
551       }
552       synchronized (mutex) {
553         return delegate().equals(o);
554       }
555     }
556 
557     @Override
558     public int hashCode() {
559       synchronized (mutex) {
560         return delegate().hashCode();
561       }
562     }
563 
564     private static final long serialVersionUID = 0;
565   }
566 
567   static <K, V> Multimap<K, V> multimap(Multimap<K, V> multimap, @Nullable Object mutex) {
568     if (multimap instanceof SynchronizedMultimap || multimap instanceof ImmutableMultimap) {
569       return multimap;
570     }
571     return new SynchronizedMultimap<>(multimap, mutex);
572   }
573 
574   private static class SynchronizedMultimap<K, V> extends SynchronizedObject
575       implements Multimap<K, V> {
576     transient Set<K> keySet;
577     transient Collection<V> valuesCollection;
578     transient Collection<Map.Entry<K, V>> entries;
579     transient Map<K, Collection<V>> asMap;
580     transient Multiset<K> keys;
581 
582     @SuppressWarnings("unchecked")
583     @Override
584     Multimap<K, V> delegate() {
585       return (Multimap<K, V>) super.delegate();
586     }
587 
588     SynchronizedMultimap(Multimap<K, V> delegate, @Nullable Object mutex) {
589       super(delegate, mutex);
590     }
591 
592     @Override
593     public int size() {
594       synchronized (mutex) {
595         return delegate().size();
596       }
597     }
598 
599     @Override
600     public boolean isEmpty() {
601       synchronized (mutex) {
602         return delegate().isEmpty();
603       }
604     }
605 
606     @Override
607     public boolean containsKey(Object key) {
608       synchronized (mutex) {
609         return delegate().containsKey(key);
610       }
611     }
612 
613     @Override
614     public boolean containsValue(Object value) {
615       synchronized (mutex) {
616         return delegate().containsValue(value);
617       }
618     }
619 
620     @Override
621     public boolean containsEntry(Object key, Object value) {
622       synchronized (mutex) {
623         return delegate().containsEntry(key, value);
624       }
625     }
626 
627     @Override
628     public Collection<V> get(K key) {
629       synchronized (mutex) {
630         return typePreservingCollection(delegate().get(key), mutex);
631       }
632     }
633 
634     @Override
635     public boolean put(K key, V value) {
636       synchronized (mutex) {
637         return delegate().put(key, value);
638       }
639     }
640 
641     @Override
642     public boolean putAll(K key, Iterable<? extends V> values) {
643       synchronized (mutex) {
644         return delegate().putAll(key, values);
645       }
646     }
647 
648     @Override
649     public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
650       synchronized (mutex) {
651         return delegate().putAll(multimap);
652       }
653     }
654 
655     @Override
656     public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
657       synchronized (mutex) {
658         return delegate().replaceValues(key, values); // copy not synchronized
659       }
660     }
661 
662     @Override
663     public boolean remove(Object key, Object value) {
664       synchronized (mutex) {
665         return delegate().remove(key, value);
666       }
667     }
668 
669     @Override
670     public Collection<V> removeAll(Object key) {
671       synchronized (mutex) {
672         return delegate().removeAll(key); // copy not synchronized
673       }
674     }
675 
676     @Override
677     public void clear() {
678       synchronized (mutex) {
679         delegate().clear();
680       }
681     }
682 
683     @Override
684     public Set<K> keySet() {
685       synchronized (mutex) {
686         if (keySet == null) {
687           keySet = typePreservingSet(delegate().keySet(), mutex);
688         }
689         return keySet;
690       }
691     }
692 
693     @Override
694     public Collection<V> values() {
695       synchronized (mutex) {
696         if (valuesCollection == null) {
697           valuesCollection = collection(delegate().values(), mutex);
698         }
699         return valuesCollection;
700       }
701     }
702 
703     @Override
704     public Collection<Map.Entry<K, V>> entries() {
705       synchronized (mutex) {
706         if (entries == null) {
707           entries = typePreservingCollection(delegate().entries(), mutex);
708         }
709         return entries;
710       }
711     }
712 
713     @Override
714     public void forEach(BiConsumer<? super K, ? super V> action) {
715       synchronized (mutex) {
716         delegate().forEach(action);
717       }
718     }
719 
720     @Override
721     public Map<K, Collection<V>> asMap() {
722       synchronized (mutex) {
723         if (asMap == null) {
724           asMap = new SynchronizedAsMap<>(delegate().asMap(), mutex);
725         }
726         return asMap;
727       }
728     }
729 
730     @Override
731     public Multiset<K> keys() {
732       synchronized (mutex) {
733         if (keys == null) {
734           keys = multiset(delegate().keys(), mutex);
735         }
736         return keys;
737       }
738     }
739 
740     @Override
741     public boolean equals(Object o) {
742       if (o == this) {
743         return true;
744       }
745       synchronized (mutex) {
746         return delegate().equals(o);
747       }
748     }
749 
750     @Override
751     public int hashCode() {
752       synchronized (mutex) {
753         return delegate().hashCode();
754       }
755     }
756 
757     private static final long serialVersionUID = 0;
758   }
759 
760   static <K, V> ListMultimap<K, V> listMultimap(
761       ListMultimap<K, V> multimap, @Nullable Object mutex) {
762     if (multimap instanceof SynchronizedListMultimap || multimap instanceof ImmutableListMultimap) {
763       return multimap;
764     }
765     return new SynchronizedListMultimap<>(multimap, mutex);
766   }
767 
768   private static class SynchronizedListMultimap<K, V> extends SynchronizedMultimap<K, V>
769       implements ListMultimap<K, V> {
770     SynchronizedListMultimap(ListMultimap<K, V> delegate, @Nullable Object mutex) {
771       super(delegate, mutex);
772     }
773 
774     @Override
775     ListMultimap<K, V> delegate() {
776       return (ListMultimap<K, V>) super.delegate();
777     }
778 
779     @Override
780     public List<V> get(K key) {
781       synchronized (mutex) {
782         return list(delegate().get(key), mutex);
783       }
784     }
785 
786     @Override
787     public List<V> removeAll(Object key) {
788       synchronized (mutex) {
789         return delegate().removeAll(key); // copy not synchronized
790       }
791     }
792 
793     @Override
794     public List<V> replaceValues(K key, Iterable<? extends V> values) {
795       synchronized (mutex) {
796         return delegate().replaceValues(key, values); // copy not synchronized
797       }
798     }
799 
800     private static final long serialVersionUID = 0;
801   }
802 
803   static <K, V> SetMultimap<K, V> setMultimap(SetMultimap<K, V> multimap, @Nullable Object mutex) {
804     if (multimap instanceof SynchronizedSetMultimap || multimap instanceof ImmutableSetMultimap) {
805       return multimap;
806     }
807     return new SynchronizedSetMultimap<>(multimap, mutex);
808   }
809 
810   private static class SynchronizedSetMultimap<K, V> extends SynchronizedMultimap<K, V>
811       implements SetMultimap<K, V> {
812     transient Set<Map.Entry<K, V>> entrySet;
813 
814     SynchronizedSetMultimap(SetMultimap<K, V> delegate, @Nullable Object mutex) {
815       super(delegate, mutex);
816     }
817 
818     @Override
819     SetMultimap<K, V> delegate() {
820       return (SetMultimap<K, V>) super.delegate();
821     }
822 
823     @Override
824     public Set<V> get(K key) {
825       synchronized (mutex) {
826         return set(delegate().get(key), mutex);
827       }
828     }
829 
830     @Override
831     public Set<V> removeAll(Object key) {
832       synchronized (mutex) {
833         return delegate().removeAll(key); // copy not synchronized
834       }
835     }
836 
837     @Override
838     public Set<V> replaceValues(K key, Iterable<? extends V> values) {
839       synchronized (mutex) {
840         return delegate().replaceValues(key, values); // copy not synchronized
841       }
842     }
843 
844     @Override
845     public Set<Map.Entry<K, V>> entries() {
846       synchronized (mutex) {
847         if (entrySet == null) {
848           entrySet = set(delegate().entries(), mutex);
849         }
850         return entrySet;
851       }
852     }
853 
854     private static final long serialVersionUID = 0;
855   }
856 
857   static <K, V> SortedSetMultimap<K, V> sortedSetMultimap(
858       SortedSetMultimap<K, V> multimap, @Nullable Object mutex) {
859     if (multimap instanceof SynchronizedSortedSetMultimap) {
860       return multimap;
861     }
862     return new SynchronizedSortedSetMultimap<>(multimap, mutex);
863   }
864 
865   private static class SynchronizedSortedSetMultimap<K, V> extends SynchronizedSetMultimap<K, V>
866       implements SortedSetMultimap<K, V> {
867     SynchronizedSortedSetMultimap(SortedSetMultimap<K, V> delegate, @Nullable Object mutex) {
868       super(delegate, mutex);
869     }
870 
871     @Override
872     SortedSetMultimap<K, V> delegate() {
873       return (SortedSetMultimap<K, V>) super.delegate();
874     }
875 
876     @Override
877     public SortedSet<V> get(K key) {
878       synchronized (mutex) {
879         return sortedSet(delegate().get(key), mutex);
880       }
881     }
882 
883     @Override
884     public SortedSet<V> removeAll(Object key) {
885       synchronized (mutex) {
886         return delegate().removeAll(key); // copy not synchronized
887       }
888     }
889 
890     @Override
891     public SortedSet<V> replaceValues(K key, Iterable<? extends V> values) {
892       synchronized (mutex) {
893         return delegate().replaceValues(key, values); // copy not synchronized
894       }
895     }
896 
897     @Override
898     public Comparator<? super V> valueComparator() {
899       synchronized (mutex) {
900         return delegate().valueComparator();
901       }
902     }
903 
904     private static final long serialVersionUID = 0;
905   }
906 
907   private static <E> Collection<E> typePreservingCollection(
908       Collection<E> collection, @Nullable Object mutex) {
909     if (collection instanceof SortedSet) {
910       return sortedSet((SortedSet<E>) collection, mutex);
911     }
912     if (collection instanceof Set) {
913       return set((Set<E>) collection, mutex);
914     }
915     if (collection instanceof List) {
916       return list((List<E>) collection, mutex);
917     }
918     return collection(collection, mutex);
919   }
920 
921   private static <E> Set<E> typePreservingSet(Set<E> set, @Nullable Object mutex) {
922     if (set instanceof SortedSet) {
923       return sortedSet((SortedSet<E>) set, mutex);
924     } else {
925       return set(set, mutex);
926     }
927   }
928 
929   private static class SynchronizedAsMapEntries<K, V>
930       extends SynchronizedSet<Map.Entry<K, Collection<V>>> {
931     SynchronizedAsMapEntries(Set<Map.Entry<K, Collection<V>>> delegate, @Nullable Object mutex) {
932       super(delegate, mutex);
933     }
934 
935     @Override
936     public Iterator<Map.Entry<K, Collection<V>>> iterator() {
937       // Must be manually synchronized.
938       return new TransformedIterator<Map.Entry<K, Collection<V>>, Map.Entry<K, Collection<V>>>(
939           super.iterator()) {
940         @Override
941         Map.Entry<K, Collection<V>> transform(final Map.Entry<K, Collection<V>> entry) {
942           return new ForwardingMapEntry<K, Collection<V>>() {
943             @Override
944             protected Map.Entry<K, Collection<V>> delegate() {
945               return entry;
946             }
947 
948             @Override
949             public Collection<V> getValue() {
950               return typePreservingCollection(entry.getValue(), mutex);
951             }
952           };
953         }
954       };
955     }
956 
957     // See Collections.CheckedMap.CheckedEntrySet for details on attacks.
958 
959     @Override
960     public Object[] toArray() {
961       synchronized (mutex) {
962         return ObjectArrays.toArrayImpl(delegate());
963       }
964     }
965 
966     @Override
967     public <T> T[] toArray(T[] array) {
968       synchronized (mutex) {
969         return ObjectArrays.toArrayImpl(delegate(), array);
970       }
971     }
972 
973     @Override
974     public boolean contains(Object o) {
975       synchronized (mutex) {
976         return Maps.containsEntryImpl(delegate(), o);
977       }
978     }
979 
980     @Override
981     public boolean containsAll(Collection<?> c) {
982       synchronized (mutex) {
983         return Collections2.containsAllImpl(delegate(), c);
984       }
985     }
986 
987     @Override
988     public boolean equals(Object o) {
989       if (o == this) {
990         return true;
991       }
992       synchronized (mutex) {
993         return Sets.equalsImpl(delegate(), o);
994       }
995     }
996 
997     @Override
998     public boolean remove(Object o) {
999       synchronized (mutex) {
1000         return Maps.removeEntryImpl(delegate(), o);
1001       }
1002     }
1003 
1004     @Override
1005     public boolean removeAll(Collection<?> c) {
1006       synchronized (mutex) {
1007         return Iterators.removeAll(delegate().iterator(), c);
1008       }
1009     }
1010 
1011     @Override
1012     public boolean retainAll(Collection<?> c) {
1013       synchronized (mutex) {
1014         return Iterators.retainAll(delegate().iterator(), c);
1015       }
1016     }
1017 
1018     private static final long serialVersionUID = 0;
1019   }
1020 
1021   @VisibleForTesting
1022   static <K, V> Map<K, V> map(Map<K, V> map, @Nullable Object mutex) {
1023     return new SynchronizedMap<>(map, mutex);
1024   }
1025 
1026   private static class SynchronizedMap<K, V> extends SynchronizedObject implements Map<K, V> {
1027     transient Set<K> keySet;
1028     transient Collection<V> values;
1029     transient Set<Map.Entry<K, V>> entrySet;
1030 
1031     SynchronizedMap(Map<K, V> delegate, @Nullable Object mutex) {
1032       super(delegate, mutex);
1033     }
1034 
1035     @SuppressWarnings("unchecked")
1036     @Override
1037     Map<K, V> delegate() {
1038       return (Map<K, V>) super.delegate();
1039     }
1040 
1041     @Override
1042     public void clear() {
1043       synchronized (mutex) {
1044         delegate().clear();
1045       }
1046     }
1047 
1048     @Override
1049     public boolean containsKey(Object key) {
1050       synchronized (mutex) {
1051         return delegate().containsKey(key);
1052       }
1053     }
1054 
1055     @Override
1056     public boolean containsValue(Object value) {
1057       synchronized (mutex) {
1058         return delegate().containsValue(value);
1059       }
1060     }
1061 
1062     @Override
1063     public Set<Map.Entry<K, V>> entrySet() {
1064       synchronized (mutex) {
1065         if (entrySet == null) {
1066           entrySet = set(delegate().entrySet(), mutex);
1067         }
1068         return entrySet;
1069       }
1070     }
1071 
1072     @Override
1073     public void forEach(BiConsumer<? super K, ? super V> action) {
1074       synchronized (mutex) {
1075         delegate().forEach(action);
1076       }
1077     }
1078 
1079     @Override
1080     public V get(Object key) {
1081       synchronized (mutex) {
1082         return delegate().get(key);
1083       }
1084     }
1085 
1086     @Override
1087     public V getOrDefault(Object key, V defaultValue) {
1088       synchronized (mutex) {
1089         return delegate().getOrDefault(key, defaultValue);
1090       }
1091     }
1092 
1093     @Override
1094     public boolean isEmpty() {
1095       synchronized (mutex) {
1096         return delegate().isEmpty();
1097       }
1098     }
1099 
1100     @Override
1101     public Set<K> keySet() {
1102       synchronized (mutex) {
1103         if (keySet == null) {
1104           keySet = set(delegate().keySet(), mutex);
1105         }
1106         return keySet;
1107       }
1108     }
1109 
1110     @Override
1111     public V put(K key, V value) {
1112       synchronized (mutex) {
1113         return delegate().put(key, value);
1114       }
1115     }
1116 
1117     @Override
1118     public V putIfAbsent(K key, V value) {
1119       synchronized (mutex) {
1120         return delegate().putIfAbsent(key, value);
1121       }
1122     }
1123 
1124     @Override
1125     public boolean replace(K key, V oldValue, V newValue) {
1126       synchronized (mutex) {
1127         return delegate().replace(key, oldValue, newValue);
1128       }
1129     }
1130 
1131     @Override
1132     public V replace(K key, V value) {
1133       synchronized (mutex) {
1134         return delegate().replace(key, value);
1135       }
1136     }
1137 
1138     @Override
1139     public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
1140       synchronized (mutex) {
1141         return delegate().computeIfAbsent(key, mappingFunction);
1142       }
1143     }
1144 
1145     @Override
1146     public V computeIfPresent(
1147         K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1148       synchronized (mutex) {
1149         return delegate().computeIfPresent(key, remappingFunction);
1150       }
1151     }
1152 
1153     @Override
1154     public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
1155       synchronized (mutex) {
1156         return delegate().compute(key, remappingFunction);
1157       }
1158     }
1159 
1160     @Override
1161     public V merge(
1162         K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
1163       synchronized (mutex) {
1164         return delegate().merge(key, value, remappingFunction);
1165       }
1166     }
1167 
1168     @Override
1169     public void putAll(Map<? extends K, ? extends V> map) {
1170       synchronized (mutex) {
1171         delegate().putAll(map);
1172       }
1173     }
1174 
1175     @Override
1176     public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
1177       synchronized (mutex) {
1178         delegate().replaceAll(function);
1179       }
1180     }
1181 
1182     @Override
1183     public V remove(Object key) {
1184       synchronized (mutex) {
1185         return delegate().remove(key);
1186       }
1187     }
1188 
1189     @Override
1190     public boolean remove(Object key, Object value) {
1191       synchronized (mutex) {
1192         return delegate().remove(key, value);
1193       }
1194     }
1195 
1196     @Override
1197     public int size() {
1198       synchronized (mutex) {
1199         return delegate().size();
1200       }
1201     }
1202 
1203     @Override
1204     public Collection<V> values() {
1205       synchronized (mutex) {
1206         if (values == null) {
1207           values = collection(delegate().values(), mutex);
1208         }
1209         return values;
1210       }
1211     }
1212 
1213     @Override
1214     public boolean equals(Object o) {
1215       if (o == this) {
1216         return true;
1217       }
1218       synchronized (mutex) {
1219         return delegate().equals(o);
1220       }
1221     }
1222 
1223     @Override
1224     public int hashCode() {
1225       synchronized (mutex) {
1226         return delegate().hashCode();
1227       }
1228     }
1229 
1230     private static final long serialVersionUID = 0;
1231   }
1232 
1233   static <K, V> SortedMap<K, V> sortedMap(SortedMap<K, V> sortedMap, @Nullable Object mutex) {
1234     return new SynchronizedSortedMap<>(sortedMap, mutex);
1235   }
1236 
1237   static class SynchronizedSortedMap<K, V> extends SynchronizedMap<K, V>
1238       implements SortedMap<K, V> {
1239 
1240     SynchronizedSortedMap(SortedMap<K, V> delegate, @Nullable Object mutex) {
1241       super(delegate, mutex);
1242     }
1243 
1244     @Override
1245     SortedMap<K, V> delegate() {
1246       return (SortedMap<K, V>) super.delegate();
1247     }
1248 
1249     @Override
1250     public Comparator<? super K> comparator() {
1251       synchronized (mutex) {
1252         return delegate().comparator();
1253       }
1254     }
1255 
1256     @Override
1257     public K firstKey() {
1258       synchronized (mutex) {
1259         return delegate().firstKey();
1260       }
1261     }
1262 
1263     @Override
1264     public SortedMap<K, V> headMap(K toKey) {
1265       synchronized (mutex) {
1266         return sortedMap(delegate().headMap(toKey), mutex);
1267       }
1268     }
1269 
1270     @Override
1271     public K lastKey() {
1272       synchronized (mutex) {
1273         return delegate().lastKey();
1274       }
1275     }
1276 
1277     @Override
1278     public SortedMap<K, V> subMap(K fromKey, K toKey) {
1279       synchronized (mutex) {
1280         return sortedMap(delegate().subMap(fromKey, toKey), mutex);
1281       }
1282     }
1283 
1284     @Override
1285     public SortedMap<K, V> tailMap(K fromKey) {
1286       synchronized (mutex) {
1287         return sortedMap(delegate().tailMap(fromKey), mutex);
1288       }
1289     }
1290 
1291     private static final long serialVersionUID = 0;
1292   }
1293 
1294   static <K, V> BiMap<K, V> biMap(BiMap<K, V> bimap, @Nullable Object mutex) {
1295     if (bimap instanceof SynchronizedBiMap || bimap instanceof ImmutableBiMap) {
1296       return bimap;
1297     }
1298     return new SynchronizedBiMap<>(bimap, mutex, null);
1299   }
1300 
1301   @VisibleForTesting
1302   static class SynchronizedBiMap<K, V> extends SynchronizedMap<K, V>
1303       implements BiMap<K, V>, Serializable {
1304     private transient Set<V> valueSet;
1305     @RetainedWith
1306     private transient BiMap<V, K> inverse;
1307 
1308     private SynchronizedBiMap(
1309         BiMap<K, V> delegate, @Nullable Object mutex, @Nullable BiMap<V, K> inverse) {
1310       super(delegate, mutex);
1311       this.inverse = inverse;
1312     }
1313 
1314     @Override
1315     BiMap<K, V> delegate() {
1316       return (BiMap<K, V>) super.delegate();
1317     }
1318 
1319     @Override
1320     public Set<V> values() {
1321       synchronized (mutex) {
1322         if (valueSet == null) {
1323           valueSet = set(delegate().values(), mutex);
1324         }
1325         return valueSet;
1326       }
1327     }
1328 
1329     @Override
1330     public V forcePut(K key, V value) {
1331       synchronized (mutex) {
1332         return delegate().forcePut(key, value);
1333       }
1334     }
1335 
1336     @Override
1337     public BiMap<V, K> inverse() {
1338       synchronized (mutex) {
1339         if (inverse == null) {
1340           inverse = new SynchronizedBiMap<>(delegate().inverse(), mutex, this);
1341         }
1342         return inverse;
1343       }
1344     }
1345 
1346     private static final long serialVersionUID = 0;
1347   }
1348 
1349   private static class SynchronizedAsMap<K, V> extends SynchronizedMap<K, Collection<V>> {
1350     transient Set<Map.Entry<K, Collection<V>>> asMapEntrySet;
1351     transient Collection<Collection<V>> asMapValues;
1352 
1353     SynchronizedAsMap(Map<K, Collection<V>> delegate, @Nullable Object mutex) {
1354       super(delegate, mutex);
1355     }
1356 
1357     @Override
1358     public Collection<V> get(Object key) {
1359       synchronized (mutex) {
1360         Collection<V> collection = super.get(key);
1361         return (collection == null) ? null : typePreservingCollection(collection, mutex);
1362       }
1363     }
1364 
1365     @Override
1366     public Set<Map.Entry<K, Collection<V>>> entrySet() {
1367       synchronized (mutex) {
1368         if (asMapEntrySet == null) {
1369           asMapEntrySet = new SynchronizedAsMapEntries<>(delegate().entrySet(), mutex);
1370         }
1371         return asMapEntrySet;
1372       }
1373     }
1374 
1375     @Override
1376     public Collection<Collection<V>> values() {
1377       synchronized (mutex) {
1378         if (asMapValues == null) {
1379           asMapValues = new SynchronizedAsMapValues<V>(delegate().values(), mutex);
1380         }
1381         return asMapValues;
1382       }
1383     }
1384 
1385     @Override
1386     public boolean containsValue(Object o) {
1387       // values() and its contains() method are both synchronized.
1388       return values().contains(o);
1389     }
1390 
1391     private static final long serialVersionUID = 0;
1392   }
1393 
1394   private static class SynchronizedAsMapValues<V> extends SynchronizedCollection<Collection<V>> {
1395     SynchronizedAsMapValues(Collection<Collection<V>> delegate, @Nullable Object mutex) {
1396       super(delegate, mutex);
1397     }
1398 
1399     @Override
1400     public Iterator<Collection<V>> iterator() {
1401       // Must be manually synchronized.
1402       return new TransformedIterator<Collection<V>, Collection<V>>(super.iterator()) {
1403         @Override
1404         Collection<V> transform(Collection<V> from) {
1405           return typePreservingCollection(from, mutex);
1406         }
1407       };
1408     }
1409 
1410     private static final long serialVersionUID = 0;
1411   }
1412 
1413   @GwtIncompatible // NavigableSet
1414   @VisibleForTesting
1415   static class SynchronizedNavigableSet<E> extends SynchronizedSortedSet<E>
1416       implements NavigableSet<E> {
1417     SynchronizedNavigableSet(NavigableSet<E> delegate, @Nullable Object mutex) {
1418       super(delegate, mutex);
1419     }
1420 
1421     @Override
1422     NavigableSet<E> delegate() {
1423       return (NavigableSet<E>) super.delegate();
1424     }
1425 
1426     @Override
1427     public E ceiling(E e) {
1428       synchronized (mutex) {
1429         return delegate().ceiling(e);
1430       }
1431     }
1432 
1433     @Override
1434     public Iterator<E> descendingIterator() {
1435       return delegate().descendingIterator(); // manually synchronized
1436     }
1437 
1438     transient NavigableSet<E> descendingSet;
1439 
1440     @Override
1441     public NavigableSet<E> descendingSet() {
1442       synchronized (mutex) {
1443         if (descendingSet == null) {
1444           NavigableSet<E> dS = Synchronized.navigableSet(delegate().descendingSet(), mutex);
1445           descendingSet = dS;
1446           return dS;
1447         }
1448         return descendingSet;
1449       }
1450     }
1451 
1452     @Override
1453     public E floor(E e) {
1454       synchronized (mutex) {
1455         return delegate().floor(e);
1456       }
1457     }
1458 
1459     @Override
1460     public NavigableSet<E> headSet(E toElement, boolean inclusive) {
1461       synchronized (mutex) {
1462         return Synchronized.navigableSet(delegate().headSet(toElement, inclusive), mutex);
1463       }
1464     }
1465 
1466     @Override
1467     public E higher(E e) {
1468       synchronized (mutex) {
1469         return delegate().higher(e);
1470       }
1471     }
1472 
1473     @Override
1474     public E lower(E e) {
1475       synchronized (mutex) {
1476         return delegate().lower(e);
1477       }
1478     }
1479 
1480     @Override
1481     public E pollFirst() {
1482       synchronized (mutex) {
1483         return delegate().pollFirst();
1484       }
1485     }
1486 
1487     @Override
1488     public E pollLast() {
1489       synchronized (mutex) {
1490         return delegate().pollLast();
1491       }
1492     }
1493 
1494     @Override
1495     public NavigableSet<E> subSet(
1496         E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) {
1497       synchronized (mutex) {
1498         return Synchronized.navigableSet(
1499             delegate().subSet(fromElement, fromInclusive, toElement, toInclusive), mutex);
1500       }
1501     }
1502 
1503     @Override
1504     public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
1505       synchronized (mutex) {
1506         return Synchronized.navigableSet(delegate().tailSet(fromElement, inclusive), mutex);
1507       }
1508     }
1509 
1510     @Override
1511     public SortedSet<E> headSet(E toElement) {
1512       return headSet(toElement, false);
1513     }
1514 
1515     @Override
1516     public SortedSet<E> subSet(E fromElement, E toElement) {
1517       return subSet(fromElement, true, toElement, false);
1518     }
1519 
1520     @Override
1521     public SortedSet<E> tailSet(E fromElement) {
1522       return tailSet(fromElement, true);
1523     }
1524 
1525     private static final long serialVersionUID = 0;
1526   }
1527 
1528   @GwtIncompatible // NavigableSet
1529   static <E> NavigableSet<E> navigableSet(NavigableSet<E> navigableSet, @Nullable Object mutex) {
1530     return new SynchronizedNavigableSet<E>(navigableSet, mutex);
1531   }
1532 
1533   @GwtIncompatible // NavigableSet
1534   static <E> NavigableSet<E> navigableSet(NavigableSet<E> navigableSet) {
1535     return navigableSet(navigableSet, null);
1536   }
1537 
1538   @GwtIncompatible // NavigableMap
1539   static <K, V> NavigableMap<K, V> navigableMap(NavigableMap<K, V> navigableMap) {
1540     return navigableMap(navigableMap, null);
1541   }
1542 
1543   @GwtIncompatible // NavigableMap
1544   static <K, V> NavigableMap<K, V> navigableMap(
1545       NavigableMap<K, V> navigableMap, @Nullable Object mutex) {
1546     return new SynchronizedNavigableMap<>(navigableMap, mutex);
1547   }
1548 
1549   @GwtIncompatible // NavigableMap
1550   @VisibleForTesting
1551   static class SynchronizedNavigableMap<K, V> extends SynchronizedSortedMap<K, V>
1552       implements NavigableMap<K, V> {
1553 
1554     SynchronizedNavigableMap(NavigableMap<K, V> delegate, @Nullable Object mutex) {
1555       super(delegate, mutex);
1556     }
1557 
1558     @Override
1559     NavigableMap<K, V> delegate() {
1560       return (NavigableMap<K, V>) super.delegate();
1561     }
1562 
1563     @Override
1564     public Entry<K, V> ceilingEntry(K key) {
1565       synchronized (mutex) {
1566         return nullableSynchronizedEntry(delegate().ceilingEntry(key), mutex);
1567       }
1568     }
1569 
1570     @Override
1571     public K ceilingKey(K key) {
1572       synchronized (mutex) {
1573         return delegate().ceilingKey(key);
1574       }
1575     }
1576 
1577     transient NavigableSet<K> descendingKeySet;
1578 
1579     @Override
1580     public NavigableSet<K> descendingKeySet() {
1581       synchronized (mutex) {
1582         if (descendingKeySet == null) {
1583           return descendingKeySet = Synchronized.navigableSet(delegate().descendingKeySet(), mutex);
1584         }
1585         return descendingKeySet;
1586       }
1587     }
1588 
1589     transient NavigableMap<K, V> descendingMap;
1590 
1591     @Override
1592     public NavigableMap<K, V> descendingMap() {
1593       synchronized (mutex) {
1594         if (descendingMap == null) {
1595           return descendingMap = navigableMap(delegate().descendingMap(), mutex);
1596         }
1597         return descendingMap;
1598       }
1599     }
1600 
1601     @Override
1602     public Entry<K, V> firstEntry() {
1603       synchronized (mutex) {
1604         return nullableSynchronizedEntry(delegate().firstEntry(), mutex);
1605       }
1606     }
1607 
1608     @Override
1609     public Entry<K, V> floorEntry(K key) {
1610       synchronized (mutex) {
1611         return nullableSynchronizedEntry(delegate().floorEntry(key), mutex);
1612       }
1613     }
1614 
1615     @Override
1616     public K floorKey(K key) {
1617       synchronized (mutex) {
1618         return delegate().floorKey(key);
1619       }
1620     }
1621 
1622     @Override
1623     public NavigableMap<K, V> headMap(K toKey, boolean inclusive) {
1624       synchronized (mutex) {
1625         return navigableMap(delegate().headMap(toKey, inclusive), mutex);
1626       }
1627     }
1628 
1629     @Override
1630     public Entry<K, V> higherEntry(K key) {
1631       synchronized (mutex) {
1632         return nullableSynchronizedEntry(delegate().higherEntry(key), mutex);
1633       }
1634     }
1635 
1636     @Override
1637     public K higherKey(K key) {
1638       synchronized (mutex) {
1639         return delegate().higherKey(key);
1640       }
1641     }
1642 
1643     @Override
1644     public Entry<K, V> lastEntry() {
1645       synchronized (mutex) {
1646         return nullableSynchronizedEntry(delegate().lastEntry(), mutex);
1647       }
1648     }
1649 
1650     @Override
1651     public Entry<K, V> lowerEntry(K key) {
1652       synchronized (mutex) {
1653         return nullableSynchronizedEntry(delegate().lowerEntry(key), mutex);
1654       }
1655     }
1656 
1657     @Override
1658     public K lowerKey(K key) {
1659       synchronized (mutex) {
1660         return delegate().lowerKey(key);
1661       }
1662     }
1663 
1664     @Override
1665     public Set<K> keySet() {
1666       return navigableKeySet();
1667     }
1668 
1669     transient NavigableSet<K> navigableKeySet;
1670 
1671     @Override
1672     public NavigableSet<K> navigableKeySet() {
1673       synchronized (mutex) {
1674         if (navigableKeySet == null) {
1675           return navigableKeySet = Synchronized.navigableSet(delegate().navigableKeySet(), mutex);
1676         }
1677         return navigableKeySet;
1678       }
1679     }
1680 
1681     @Override
1682     public Entry<K, V> pollFirstEntry() {
1683       synchronized (mutex) {
1684         return nullableSynchronizedEntry(delegate().pollFirstEntry(), mutex);
1685       }
1686     }
1687 
1688     @Override
1689     public Entry<K, V> pollLastEntry() {
1690       synchronized (mutex) {
1691         return nullableSynchronizedEntry(delegate().pollLastEntry(), mutex);
1692       }
1693     }
1694 
1695     @Override
1696     public NavigableMap<K, V> subMap(
1697         K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) {
1698       synchronized (mutex) {
1699         return navigableMap(delegate().subMap(fromKey, fromInclusive, toKey, toInclusive), mutex);
1700       }
1701     }
1702 
1703     @Override
1704     public NavigableMap<K, V> tailMap(K fromKey, boolean inclusive) {
1705       synchronized (mutex) {
1706         return navigableMap(delegate().tailMap(fromKey, inclusive), mutex);
1707       }
1708     }
1709 
1710     @Override
1711     public SortedMap<K, V> headMap(K toKey) {
1712       return headMap(toKey, false);
1713     }
1714 
1715     @Override
1716     public SortedMap<K, V> subMap(K fromKey, K toKey) {
1717       return subMap(fromKey, true, toKey, false);
1718     }
1719 
1720     @Override
1721     public SortedMap<K, V> tailMap(K fromKey) {
1722       return tailMap(fromKey, true);
1723     }
1724 
1725     private static final long serialVersionUID = 0;
1726   }
1727 
1728   @GwtIncompatible // works but is needed only for NavigableMap
1729   private static <K, V> Entry<K, V> nullableSynchronizedEntry(
1730       @Nullable Entry<K, V> entry, @Nullable Object mutex) {
1731     if (entry == null) {
1732       return null;
1733     }
1734     return new SynchronizedEntry<>(entry, mutex);
1735   }
1736 
1737   @GwtIncompatible // works but is needed only for NavigableMap
1738   private static class SynchronizedEntry<K, V> extends SynchronizedObject implements Entry<K, V> {
1739 
1740     SynchronizedEntry(Entry<K, V> delegate, @Nullable Object mutex) {
1741       super(delegate, mutex);
1742     }
1743 
1744     @SuppressWarnings("unchecked") // guaranteed by the constructor
1745     @Override
1746     Entry<K, V> delegate() {
1747       return (Entry<K, V>) super.delegate();
1748     }
1749 
1750     @Override
1751     public boolean equals(Object obj) {
1752       synchronized (mutex) {
1753         return delegate().equals(obj);
1754       }
1755     }
1756 
1757     @Override
1758     public int hashCode() {
1759       synchronized (mutex) {
1760         return delegate().hashCode();
1761       }
1762     }
1763 
1764     @Override
1765     public K getKey() {
1766       synchronized (mutex) {
1767         return delegate().getKey();
1768       }
1769     }
1770 
1771     @Override
1772     public V getValue() {
1773       synchronized (mutex) {
1774         return delegate().getValue();
1775       }
1776     }
1777 
1778     @Override
1779     public V setValue(V value) {
1780       synchronized (mutex) {
1781         return delegate().setValue(value);
1782       }
1783     }
1784 
1785     private static final long serialVersionUID = 0;
1786   }
1787 
1788   static <E> Queue<E> queue(Queue<E> queue, @Nullable Object mutex) {
1789     return (queue instanceof SynchronizedQueue) ? queue : new SynchronizedQueue<E>(queue, mutex);
1790   }
1791 
1792   private static class SynchronizedQueue<E> extends SynchronizedCollection<E> implements Queue<E> {
1793 
1794     SynchronizedQueue(Queue<E> delegate, @Nullable Object mutex) {
1795       super(delegate, mutex);
1796     }
1797 
1798     @Override
1799     Queue<E> delegate() {
1800       return (Queue<E>) super.delegate();
1801     }
1802 
1803     @Override
1804     public E element() {
1805       synchronized (mutex) {
1806         return delegate().element();
1807       }
1808     }
1809 
1810     @Override
1811     public boolean offer(E e) {
1812       synchronized (mutex) {
1813         return delegate().offer(e);
1814       }
1815     }
1816 
1817     @Override
1818     public E peek() {
1819       synchronized (mutex) {
1820         return delegate().peek();
1821       }
1822     }
1823 
1824     @Override
1825     public E poll() {
1826       synchronized (mutex) {
1827         return delegate().poll();
1828       }
1829     }
1830 
1831     @Override
1832     public E remove() {
1833       synchronized (mutex) {
1834         return delegate().remove();
1835       }
1836     }
1837 
1838     private static final long serialVersionUID = 0;
1839   }
1840 
1841   static <E> Deque<E> deque(Deque<E> deque, @Nullable Object mutex) {
1842     return new SynchronizedDeque<E>(deque, mutex);
1843   }
1844 
1845   private static final class SynchronizedDeque<E> extends SynchronizedQueue<E> implements Deque<E> {
1846 
1847     SynchronizedDeque(Deque<E> delegate, @Nullable Object mutex) {
1848       super(delegate, mutex);
1849     }
1850 
1851     @Override
1852     Deque<E> delegate() {
1853       return (Deque<E>) super.delegate();
1854     }
1855 
1856     @Override
1857     public void addFirst(E e) {
1858       synchronized (mutex) {
1859         delegate().addFirst(e);
1860       }
1861     }
1862 
1863     @Override
1864     public void addLast(E e) {
1865       synchronized (mutex) {
1866         delegate().addLast(e);
1867       }
1868     }
1869 
1870     @Override
1871     public boolean offerFirst(E e) {
1872       synchronized (mutex) {
1873         return delegate().offerFirst(e);
1874       }
1875     }
1876 
1877     @Override
1878     public boolean offerLast(E e) {
1879       synchronized (mutex) {
1880         return delegate().offerLast(e);
1881       }
1882     }
1883 
1884     @Override
1885     public E removeFirst() {
1886       synchronized (mutex) {
1887         return delegate().removeFirst();
1888       }
1889     }
1890 
1891     @Override
1892     public E removeLast() {
1893       synchronized (mutex) {
1894         return delegate().removeLast();
1895       }
1896     }
1897 
1898     @Override
1899     public E pollFirst() {
1900       synchronized (mutex) {
1901         return delegate().pollFirst();
1902       }
1903     }
1904 
1905     @Override
1906     public E pollLast() {
1907       synchronized (mutex) {
1908         return delegate().pollLast();
1909       }
1910     }
1911 
1912     @Override
1913     public E getFirst() {
1914       synchronized (mutex) {
1915         return delegate().getFirst();
1916       }
1917     }
1918 
1919     @Override
1920     public E getLast() {
1921       synchronized (mutex) {
1922         return delegate().getLast();
1923       }
1924     }
1925 
1926     @Override
1927     public E peekFirst() {
1928       synchronized (mutex) {
1929         return delegate().peekFirst();
1930       }
1931     }
1932 
1933     @Override
1934     public E peekLast() {
1935       synchronized (mutex) {
1936         return delegate().peekLast();
1937       }
1938     }
1939 
1940     @Override
1941     public boolean removeFirstOccurrence(Object o) {
1942       synchronized (mutex) {
1943         return delegate().removeFirstOccurrence(o);
1944       }
1945     }
1946 
1947     @Override
1948     public boolean removeLastOccurrence(Object o) {
1949       synchronized (mutex) {
1950         return delegate().removeLastOccurrence(o);
1951       }
1952     }
1953 
1954     @Override
1955     public void push(E e) {
1956       synchronized (mutex) {
1957         delegate().push(e);
1958       }
1959     }
1960 
1961     @Override
1962     public E pop() {
1963       synchronized (mutex) {
1964         return delegate().pop();
1965       }
1966     }
1967 
1968     @Override
1969     public Iterator<E> descendingIterator() {
1970       synchronized (mutex) {
1971         return delegate().descendingIterator();
1972       }
1973     }
1974 
1975     private static final long serialVersionUID = 0;
1976   }
1977   
1978   static <R, C, V> Table<R, C, V> table(Table<R, C, V> table, Object mutex) {
1979     return new SynchronizedTable<>(table, mutex);
1980   }
1981 
1982   private static final class SynchronizedTable<R, C, V> extends SynchronizedObject
1983       implements Table<R, C, V> {
1984 
1985     SynchronizedTable(Table<R, C, V> delegate, Object mutex) {
1986       super(delegate, mutex);
1987     }
1988 
1989     @SuppressWarnings("unchecked")
1990     @Override
1991     Table<R, C, V> delegate() {
1992       return (Table<R, C, V>) super.delegate();
1993     }
1994 
1995     @Override
1996     public boolean contains(@Nullable Object rowKey, @Nullable Object columnKey) {
1997       synchronized (mutex) {
1998         return delegate().contains(rowKey, columnKey);
1999       }
2000     }
2001 
2002     @Override
2003     public boolean containsRow(@Nullable Object rowKey) {
2004       synchronized (mutex) {
2005         return delegate().containsRow(rowKey);
2006       }
2007     }
2008 
2009     @Override
2010     public boolean containsColumn(@Nullable Object columnKey) {
2011       synchronized (mutex) {
2012         return delegate().containsColumn(columnKey);
2013       }
2014     }
2015 
2016     @Override
2017     public boolean containsValue(@Nullable Object value) {
2018       synchronized (mutex) {
2019         return delegate().containsValue(value);
2020       }
2021     }
2022 
2023     @Override
2024     public V get(@Nullable Object rowKey, @Nullable Object columnKey) {
2025       synchronized (mutex) {
2026         return delegate().get(rowKey, columnKey);
2027       }
2028     }
2029 
2030     @Override
2031     public boolean isEmpty() {
2032       synchronized (mutex) {
2033         return delegate().isEmpty();
2034       }
2035     }
2036 
2037     @Override
2038     public int size() {
2039       synchronized (mutex) {
2040         return delegate().size();
2041       }
2042     }
2043 
2044     @Override
2045     public void clear() {
2046       synchronized (mutex) {
2047         delegate().clear();
2048       }
2049     }
2050 
2051     @Override
2052     public V put(@Nullable R rowKey, @Nullable C columnKey, @Nullable V value) {
2053       synchronized (mutex) {
2054         return delegate().put(rowKey, columnKey, value);
2055       }
2056     }
2057 
2058     @Override
2059     public void putAll(Table<? extends R, ? extends C, ? extends V> table) {
2060       synchronized (mutex) {
2061         delegate().putAll(table);
2062       }
2063     }
2064 
2065     @Override
2066     public V remove(@Nullable Object rowKey, @Nullable Object columnKey) {
2067       synchronized (mutex) {
2068         return delegate().remove(rowKey, columnKey);
2069       }
2070     }
2071 
2072     @Override
2073     public Map<C, V> row(@Nullable R rowKey) {
2074       synchronized (mutex) {
2075         return map(delegate().row(rowKey), mutex);
2076       }
2077     }
2078 
2079     @Override
2080     public Map<R, V> column(@Nullable C columnKey) {
2081       synchronized (mutex) {
2082         return map(delegate().column(columnKey), mutex);
2083       }
2084     }
2085 
2086     @Override
2087     public Set<Cell<R, C, V>> cellSet() {
2088       synchronized (mutex) {
2089         return set(delegate().cellSet(), mutex);
2090       }
2091     }
2092 
2093     @Override
2094     public Set<R> rowKeySet() {
2095       synchronized (mutex) {
2096         return set(delegate().rowKeySet(), mutex);
2097       }
2098     }
2099 
2100     @Override
2101     public Set<C> columnKeySet() {
2102       synchronized (mutex) {
2103         return set(delegate().columnKeySet(), mutex);
2104       }
2105     }
2106 
2107     @Override
2108     public Collection<V> values() {
2109       synchronized (mutex) {
2110         return collection(delegate().values(), mutex);
2111       }
2112     }
2113 
2114     @Override
2115     public Map<R, Map<C, V>> rowMap() {
2116       synchronized (mutex) {
2117         return map(
2118             Maps.transformValues(
2119                 delegate().rowMap(),
2120                 new com.google.common.base.Function<Map<C, V>, Map<C, V>>() {
2121                   @Override
2122                   public Map<C, V> apply(Map<C, V> t) {
2123                     return map(t, mutex);
2124                   }
2125                 }),
2126             mutex);
2127       }
2128     }
2129 
2130     @Override
2131     public Map<C, Map<R, V>> columnMap() {
2132       synchronized (mutex) {
2133         return map(
2134             Maps.transformValues(
2135                 delegate().columnMap(),
2136                 new com.google.common.base.Function<Map<R, V>, Map<R, V>>() {
2137                   @Override
2138                   public Map<R, V> apply(Map<R, V> t) {
2139                     return map(t, mutex);
2140                   }
2141                 }),
2142             mutex);
2143       }
2144     }
2145 
2146     @Override
2147     public int hashCode() {
2148       synchronized (mutex) {
2149         return delegate().hashCode();
2150       }
2151     }
2152 
2153     @Override
2154     public boolean equals(@Nullable Object obj) {
2155       if (this == obj) {
2156         return true;
2157       }
2158       synchronized (mutex) {
2159         return delegate().equals(obj);
2160       }
2161     }
2162   }
2163 }