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