All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.common.collect.Synchronized Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version
/*
 * Copyright (C) 2007 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.common.collect;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.annotations.GwtCompatible;
import com.google.common.annotations.GwtIncompatible;
import com.google.common.annotations.J2ktIncompatible;
import com.google.common.annotations.VisibleForTesting;
import com.google.j2objc.annotations.RetainedWith;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Collection;
import java.util.Comparator;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.NavigableMap;
import java.util.NavigableSet;
import java.util.Queue;
import java.util.RandomAccess;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import java.util.Spliterator;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;
import javax.annotation.CheckForNull;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * Synchronized collection views. The returned synchronized collection views are serializable if the
 * backing collection and the mutex are serializable.
 *
 * 

If {@code null} is passed as the {@code mutex} parameter to any of this class's top-level * methods or inner class constructors, the created object uses itself as the synchronization mutex. * *

This class should be used by other collection classes only. * * @author Mike Bostock * @author Jared Levy */ @GwtCompatible(emulated = true) @ElementTypesAreNonnullByDefault /* * I have decided not to bother adding @ParametricNullness annotations in this class. Adding them is * a lot of busy work, and the annotation matters only when the APIs to be annotated are visible to * Kotlin code. In this class, nothing is publicly visible (nor exposed indirectly through a * publicly visible subclass), and I doubt any of our current or future Kotlin extensions for the * package will refer to the class. Plus, @ParametricNullness is only a temporary workaround, * anyway, so we just need to get by without the annotations here until Kotlin better understands * our other nullness annotations. */ final class Synchronized { private Synchronized() {} static class SynchronizedObject implements Serializable { final Object delegate; final Object mutex; SynchronizedObject(Object delegate, @CheckForNull Object mutex) { this.delegate = checkNotNull(delegate); this.mutex = (mutex == null) ? this : mutex; } Object delegate() { return delegate; } // No equals and hashCode; see ForwardingObject for details. @Override public String toString() { synchronized (mutex) { return delegate.toString(); } } // Serialization invokes writeObject only when it's private. // The SynchronizedObject subclasses don't need a writeObject method since // they don't contain any non-transient member variables, while the // following writeObject() handles the SynchronizedObject members. @GwtIncompatible // java.io.ObjectOutputStream @J2ktIncompatible private void writeObject(ObjectOutputStream stream) throws IOException { synchronized (mutex) { stream.defaultWriteObject(); } } @GwtIncompatible // not needed in emulated source @J2ktIncompatible private static final long serialVersionUID = 0; } private static Collection collection( Collection collection, @CheckForNull Object mutex) { return new SynchronizedCollection(collection, mutex); } @VisibleForTesting static class SynchronizedCollection extends SynchronizedObject implements Collection { private SynchronizedCollection(Collection delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @SuppressWarnings("unchecked") @Override Collection delegate() { return (Collection) super.delegate(); } @Override public boolean add(E e) { synchronized (mutex) { return delegate().add(e); } } @Override public boolean addAll(Collection c) { synchronized (mutex) { return delegate().addAll(c); } } @Override public void clear() { synchronized (mutex) { delegate().clear(); } } @Override public boolean contains(@CheckForNull Object o) { synchronized (mutex) { return delegate().contains(o); } } @Override public boolean containsAll(Collection c) { synchronized (mutex) { return delegate().containsAll(c); } } @Override public boolean isEmpty() { synchronized (mutex) { return delegate().isEmpty(); } } @Override public Iterator iterator() { return delegate().iterator(); // manually synchronized } @Override public Spliterator spliterator() { synchronized (mutex) { return delegate().spliterator(); } } @Override public Stream stream() { synchronized (mutex) { return delegate().stream(); } } @Override public Stream parallelStream() { synchronized (mutex) { return delegate().parallelStream(); } } @Override public void forEach(Consumer action) { synchronized (mutex) { delegate().forEach(action); } } @Override public boolean remove(@CheckForNull Object o) { synchronized (mutex) { return delegate().remove(o); } } @Override public boolean removeAll(Collection c) { synchronized (mutex) { return delegate().removeAll(c); } } @Override public boolean retainAll(Collection c) { synchronized (mutex) { return delegate().retainAll(c); } } @Override public boolean removeIf(Predicate filter) { synchronized (mutex) { return delegate().removeIf(filter); } } @Override public int size() { synchronized (mutex) { return delegate().size(); } } @Override public @Nullable Object[] toArray() { synchronized (mutex) { return delegate().toArray(); } } @Override @SuppressWarnings("nullness") // b/192354773 in our checker affects toArray declarations public T[] toArray(T[] a) { synchronized (mutex) { return delegate().toArray(a); } } private static final long serialVersionUID = 0; } @VisibleForTesting static Set set(Set set, @CheckForNull Object mutex) { return new SynchronizedSet(set, mutex); } static class SynchronizedSet extends SynchronizedCollection implements Set { SynchronizedSet(Set delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override Set delegate() { return (Set) super.delegate(); } @Override public boolean equals(@CheckForNull Object o) { if (o == this) { return true; } synchronized (mutex) { return delegate().equals(o); } } @Override public int hashCode() { synchronized (mutex) { return delegate().hashCode(); } } private static final long serialVersionUID = 0; } private static SortedSet sortedSet( SortedSet set, @CheckForNull Object mutex) { return new SynchronizedSortedSet(set, mutex); } static class SynchronizedSortedSet extends SynchronizedSet implements SortedSet { SynchronizedSortedSet(SortedSet delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override SortedSet delegate() { return (SortedSet) super.delegate(); } @Override @CheckForNull public Comparator comparator() { synchronized (mutex) { return delegate().comparator(); } } @Override public SortedSet subSet(E fromElement, E toElement) { synchronized (mutex) { return sortedSet(delegate().subSet(fromElement, toElement), mutex); } } @Override public SortedSet headSet(E toElement) { synchronized (mutex) { return sortedSet(delegate().headSet(toElement), mutex); } } @Override public SortedSet tailSet(E fromElement) { synchronized (mutex) { return sortedSet(delegate().tailSet(fromElement), mutex); } } @Override public E first() { synchronized (mutex) { return delegate().first(); } } @Override public E last() { synchronized (mutex) { return delegate().last(); } } private static final long serialVersionUID = 0; } private static List list( List list, @CheckForNull Object mutex) { return (list instanceof RandomAccess) ? new SynchronizedRandomAccessList(list, mutex) : new SynchronizedList(list, mutex); } private static class SynchronizedList extends SynchronizedCollection implements List { SynchronizedList(List delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override List delegate() { return (List) super.delegate(); } @Override public void add(int index, E element) { synchronized (mutex) { delegate().add(index, element); } } @Override public boolean addAll(int index, Collection c) { synchronized (mutex) { return delegate().addAll(index, c); } } @Override public E get(int index) { synchronized (mutex) { return delegate().get(index); } } @Override public int indexOf(@CheckForNull Object o) { synchronized (mutex) { return delegate().indexOf(o); } } @Override public int lastIndexOf(@CheckForNull Object o) { synchronized (mutex) { return delegate().lastIndexOf(o); } } @Override public ListIterator listIterator() { return delegate().listIterator(); // manually synchronized } @Override public ListIterator listIterator(int index) { return delegate().listIterator(index); // manually synchronized } @Override public E remove(int index) { synchronized (mutex) { return delegate().remove(index); } } @Override public E set(int index, E element) { synchronized (mutex) { return delegate().set(index, element); } } @Override public void replaceAll(UnaryOperator operator) { synchronized (mutex) { delegate().replaceAll(operator); } } @Override public void sort(@Nullable Comparator c) { synchronized (mutex) { delegate().sort(c); } } @Override public List subList(int fromIndex, int toIndex) { synchronized (mutex) { return list(delegate().subList(fromIndex, toIndex), mutex); } } @Override public boolean equals(@CheckForNull Object o) { if (o == this) { return true; } synchronized (mutex) { return delegate().equals(o); } } @Override public int hashCode() { synchronized (mutex) { return delegate().hashCode(); } } private static final long serialVersionUID = 0; } private static class SynchronizedRandomAccessList extends SynchronizedList implements RandomAccess { SynchronizedRandomAccessList(List list, @CheckForNull Object mutex) { super(list, mutex); } private static final long serialVersionUID = 0; } static Multiset multiset( Multiset multiset, @CheckForNull Object mutex) { if (multiset instanceof SynchronizedMultiset || multiset instanceof ImmutableMultiset) { return multiset; } return new SynchronizedMultiset(multiset, mutex); } private static class SynchronizedMultiset extends SynchronizedCollection implements Multiset { @CheckForNull transient Set elementSet; @CheckForNull transient Set> entrySet; SynchronizedMultiset(Multiset delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override Multiset delegate() { return (Multiset) super.delegate(); } @Override public int count(@CheckForNull Object o) { synchronized (mutex) { return delegate().count(o); } } @Override public int add(@ParametricNullness E e, int n) { synchronized (mutex) { return delegate().add(e, n); } } @Override public int remove(@CheckForNull Object o, int n) { synchronized (mutex) { return delegate().remove(o, n); } } @Override public int setCount(@ParametricNullness E element, int count) { synchronized (mutex) { return delegate().setCount(element, count); } } @Override public boolean setCount(@ParametricNullness E element, int oldCount, int newCount) { synchronized (mutex) { return delegate().setCount(element, oldCount, newCount); } } @Override public Set elementSet() { synchronized (mutex) { if (elementSet == null) { elementSet = typePreservingSet(delegate().elementSet(), mutex); } return elementSet; } } @Override public Set> entrySet() { synchronized (mutex) { if (entrySet == null) { entrySet = typePreservingSet(delegate().entrySet(), mutex); } return entrySet; } } @Override public boolean equals(@CheckForNull Object o) { if (o == this) { return true; } synchronized (mutex) { return delegate().equals(o); } } @Override public int hashCode() { synchronized (mutex) { return delegate().hashCode(); } } private static final long serialVersionUID = 0; } static Multimap multimap( Multimap multimap, @CheckForNull Object mutex) { if (multimap instanceof SynchronizedMultimap || multimap instanceof BaseImmutableMultimap) { return multimap; } return new SynchronizedMultimap<>(multimap, mutex); } private static class SynchronizedMultimap extends SynchronizedObject implements Multimap { @CheckForNull transient Set keySet; @CheckForNull transient Collection valuesCollection; @CheckForNull transient Collection> entries; @CheckForNull transient Map> asMap; @CheckForNull transient Multiset keys; @SuppressWarnings("unchecked") @Override Multimap delegate() { return (Multimap) super.delegate(); } SynchronizedMultimap(Multimap delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override public int size() { synchronized (mutex) { return delegate().size(); } } @Override public boolean isEmpty() { synchronized (mutex) { return delegate().isEmpty(); } } @Override public boolean containsKey(@CheckForNull Object key) { synchronized (mutex) { return delegate().containsKey(key); } } @Override public boolean containsValue(@CheckForNull Object value) { synchronized (mutex) { return delegate().containsValue(value); } } @Override public boolean containsEntry(@CheckForNull Object key, @CheckForNull Object value) { synchronized (mutex) { return delegate().containsEntry(key, value); } } @Override public Collection get(@ParametricNullness K key) { synchronized (mutex) { return typePreservingCollection(delegate().get(key), mutex); } } @Override public boolean put(@ParametricNullness K key, @ParametricNullness V value) { synchronized (mutex) { return delegate().put(key, value); } } @Override public boolean putAll(@ParametricNullness K key, Iterable values) { synchronized (mutex) { return delegate().putAll(key, values); } } @Override public boolean putAll(Multimap multimap) { synchronized (mutex) { return delegate().putAll(multimap); } } @Override public Collection replaceValues(@ParametricNullness K key, Iterable values) { synchronized (mutex) { return delegate().replaceValues(key, values); // copy not synchronized } } @Override public boolean remove(@CheckForNull Object key, @CheckForNull Object value) { synchronized (mutex) { return delegate().remove(key, value); } } @Override public Collection removeAll(@CheckForNull Object key) { synchronized (mutex) { return delegate().removeAll(key); // copy not synchronized } } @Override public void clear() { synchronized (mutex) { delegate().clear(); } } @Override public Set keySet() { synchronized (mutex) { if (keySet == null) { keySet = typePreservingSet(delegate().keySet(), mutex); } return keySet; } } @Override public Collection values() { synchronized (mutex) { if (valuesCollection == null) { valuesCollection = collection(delegate().values(), mutex); } return valuesCollection; } } @Override public Collection> entries() { synchronized (mutex) { if (entries == null) { entries = typePreservingCollection(delegate().entries(), mutex); } return entries; } } @Override public void forEach(BiConsumer action) { synchronized (mutex) { delegate().forEach(action); } } @Override public Map> asMap() { synchronized (mutex) { if (asMap == null) { asMap = new SynchronizedAsMap<>(delegate().asMap(), mutex); } return asMap; } } @Override public Multiset keys() { synchronized (mutex) { if (keys == null) { keys = multiset(delegate().keys(), mutex); } return keys; } } @Override public boolean equals(@CheckForNull Object o) { if (o == this) { return true; } synchronized (mutex) { return delegate().equals(o); } } @Override public int hashCode() { synchronized (mutex) { return delegate().hashCode(); } } private static final long serialVersionUID = 0; } static ListMultimap listMultimap( ListMultimap multimap, @CheckForNull Object mutex) { if (multimap instanceof SynchronizedListMultimap || multimap instanceof BaseImmutableMultimap) { return multimap; } return new SynchronizedListMultimap<>(multimap, mutex); } private static class SynchronizedListMultimap< K extends @Nullable Object, V extends @Nullable Object> extends SynchronizedMultimap implements ListMultimap { SynchronizedListMultimap(ListMultimap delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override ListMultimap delegate() { return (ListMultimap) super.delegate(); } @Override public List get(K key) { synchronized (mutex) { return list(delegate().get(key), mutex); } } @Override public List removeAll(@CheckForNull Object key) { synchronized (mutex) { return delegate().removeAll(key); // copy not synchronized } } @Override public List replaceValues(K key, Iterable values) { synchronized (mutex) { return delegate().replaceValues(key, values); // copy not synchronized } } private static final long serialVersionUID = 0; } static SetMultimap setMultimap( SetMultimap multimap, @CheckForNull Object mutex) { if (multimap instanceof SynchronizedSetMultimap || multimap instanceof BaseImmutableMultimap) { return multimap; } return new SynchronizedSetMultimap<>(multimap, mutex); } private static class SynchronizedSetMultimap< K extends @Nullable Object, V extends @Nullable Object> extends SynchronizedMultimap implements SetMultimap { @CheckForNull transient Set> entrySet; SynchronizedSetMultimap(SetMultimap delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override SetMultimap delegate() { return (SetMultimap) super.delegate(); } @Override public Set get(K key) { synchronized (mutex) { return set(delegate().get(key), mutex); } } @Override public Set removeAll(@CheckForNull Object key) { synchronized (mutex) { return delegate().removeAll(key); // copy not synchronized } } @Override public Set replaceValues(K key, Iterable values) { synchronized (mutex) { return delegate().replaceValues(key, values); // copy not synchronized } } @Override public Set> entries() { synchronized (mutex) { if (entrySet == null) { entrySet = set(delegate().entries(), mutex); } return entrySet; } } private static final long serialVersionUID = 0; } static SortedSetMultimap sortedSetMultimap( SortedSetMultimap multimap, @CheckForNull Object mutex) { if (multimap instanceof SynchronizedSortedSetMultimap) { return multimap; } return new SynchronizedSortedSetMultimap<>(multimap, mutex); } private static class SynchronizedSortedSetMultimap< K extends @Nullable Object, V extends @Nullable Object> extends SynchronizedSetMultimap implements SortedSetMultimap { SynchronizedSortedSetMultimap(SortedSetMultimap delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override SortedSetMultimap delegate() { return (SortedSetMultimap) super.delegate(); } @Override public SortedSet get(K key) { synchronized (mutex) { return sortedSet(delegate().get(key), mutex); } } @Override public SortedSet removeAll(@CheckForNull Object key) { synchronized (mutex) { return delegate().removeAll(key); // copy not synchronized } } @Override public SortedSet replaceValues(K key, Iterable values) { synchronized (mutex) { return delegate().replaceValues(key, values); // copy not synchronized } } @Override @CheckForNull public Comparator valueComparator() { synchronized (mutex) { return delegate().valueComparator(); } } private static final long serialVersionUID = 0; } private static Collection typePreservingCollection( Collection collection, @CheckForNull Object mutex) { if (collection instanceof SortedSet) { return sortedSet((SortedSet) collection, mutex); } if (collection instanceof Set) { return set((Set) collection, mutex); } if (collection instanceof List) { return list((List) collection, mutex); } return collection(collection, mutex); } private static Set typePreservingSet( Set set, @CheckForNull Object mutex) { if (set instanceof SortedSet) { return sortedSet((SortedSet) set, mutex); } else { return set(set, mutex); } } private static class SynchronizedAsMapEntries< K extends @Nullable Object, V extends @Nullable Object> extends SynchronizedSet>> { SynchronizedAsMapEntries( Set>> delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override public Iterator>> iterator() { // Must be manually synchronized. return new TransformedIterator>, Map.Entry>>( super.iterator()) { @Override Map.Entry> transform(final Map.Entry> entry) { return new ForwardingMapEntry>() { @Override protected Map.Entry> delegate() { return entry; } @Override public Collection getValue() { return typePreservingCollection(entry.getValue(), mutex); } }; } }; } // See Collections.CheckedMap.CheckedEntrySet for details on attacks. @Override public @Nullable Object[] toArray() { synchronized (mutex) { /* * toArrayImpl returns `@Nullable Object[]` rather than `Object[]` but only because it can * be used with collections that may contain null. This collection never contains nulls, so * we could return `Object[]`. But this class is private and J2KT cannot change return types * in overrides, so we declare `@Nullable Object[]` as the return type. */ return ObjectArrays.toArrayImpl(delegate()); } } @Override @SuppressWarnings("nullness") // b/192354773 in our checker affects toArray declarations public T[] toArray(T[] array) { synchronized (mutex) { return ObjectArrays.toArrayImpl(delegate(), array); } } @Override public boolean contains(@CheckForNull Object o) { synchronized (mutex) { return Maps.containsEntryImpl(delegate(), o); } } @Override public boolean containsAll(Collection c) { synchronized (mutex) { return Collections2.containsAllImpl(delegate(), c); } } @Override public boolean equals(@CheckForNull Object o) { if (o == this) { return true; } synchronized (mutex) { return Sets.equalsImpl(delegate(), o); } } @Override public boolean remove(@CheckForNull Object o) { synchronized (mutex) { return Maps.removeEntryImpl(delegate(), o); } } @Override public boolean removeAll(Collection c) { synchronized (mutex) { return Iterators.removeAll(delegate().iterator(), c); } } @Override public boolean retainAll(Collection c) { synchronized (mutex) { return Iterators.retainAll(delegate().iterator(), c); } } private static final long serialVersionUID = 0; } @VisibleForTesting static Map map( Map map, @CheckForNull Object mutex) { return new SynchronizedMap<>(map, mutex); } private static class SynchronizedMap extends SynchronizedObject implements Map { @CheckForNull transient Set keySet; @CheckForNull transient Collection values; @CheckForNull transient Set> entrySet; SynchronizedMap(Map delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @SuppressWarnings("unchecked") @Override Map delegate() { return (Map) super.delegate(); } @Override public void clear() { synchronized (mutex) { delegate().clear(); } } @Override public boolean containsKey(@CheckForNull Object key) { synchronized (mutex) { return delegate().containsKey(key); } } @Override public boolean containsValue(@CheckForNull Object value) { synchronized (mutex) { return delegate().containsValue(value); } } @Override public Set> entrySet() { synchronized (mutex) { if (entrySet == null) { entrySet = set(delegate().entrySet(), mutex); } return entrySet; } } @Override public void forEach(BiConsumer action) { synchronized (mutex) { delegate().forEach(action); } } @Override @CheckForNull public V get(@CheckForNull Object key) { synchronized (mutex) { return delegate().get(key); } } @Override @CheckForNull public V getOrDefault(@CheckForNull Object key, @CheckForNull V defaultValue) { synchronized (mutex) { return delegate().getOrDefault(key, defaultValue); } } @Override public boolean isEmpty() { synchronized (mutex) { return delegate().isEmpty(); } } @Override public Set keySet() { synchronized (mutex) { if (keySet == null) { keySet = set(delegate().keySet(), mutex); } return keySet; } } @Override @CheckForNull public V put(K key, V value) { synchronized (mutex) { return delegate().put(key, value); } } @Override @CheckForNull public V putIfAbsent(K key, V value) { synchronized (mutex) { return delegate().putIfAbsent(key, value); } } @Override public boolean replace(K key, V oldValue, V newValue) { synchronized (mutex) { return delegate().replace(key, oldValue, newValue); } } @Override @CheckForNull public V replace(K key, V value) { synchronized (mutex) { return delegate().replace(key, value); } } @Override public V computeIfAbsent(K key, Function mappingFunction) { synchronized (mutex) { return delegate().computeIfAbsent(key, mappingFunction); } } @Override public V computeIfPresent( K key, BiFunction remappingFunction) { synchronized (mutex) { return delegate().computeIfPresent(key, remappingFunction); } } @Override public V compute( K key, BiFunction remappingFunction) { synchronized (mutex) { return delegate().compute(key, remappingFunction); } } @Override @CheckForNull public V merge( K key, V value, BiFunction remappingFunction) { synchronized (mutex) { return delegate().merge(key, value, remappingFunction); } } @Override public void putAll(Map map) { synchronized (mutex) { delegate().putAll(map); } } @Override public void replaceAll(BiFunction function) { synchronized (mutex) { delegate().replaceAll(function); } } @Override @CheckForNull public V remove(@CheckForNull Object key) { synchronized (mutex) { return delegate().remove(key); } } @Override public boolean remove(@CheckForNull Object key, @CheckForNull Object value) { synchronized (mutex) { return delegate().remove(key, value); } } @Override public int size() { synchronized (mutex) { return delegate().size(); } } @Override public Collection values() { synchronized (mutex) { if (values == null) { values = collection(delegate().values(), mutex); } return values; } } @Override public boolean equals(@CheckForNull Object o) { if (o == this) { return true; } synchronized (mutex) { return delegate().equals(o); } } @Override public int hashCode() { synchronized (mutex) { return delegate().hashCode(); } } private static final long serialVersionUID = 0; } static SortedMap sortedMap( SortedMap sortedMap, @CheckForNull Object mutex) { return new SynchronizedSortedMap<>(sortedMap, mutex); } static class SynchronizedSortedMap extends SynchronizedMap implements SortedMap { SynchronizedSortedMap(SortedMap delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override SortedMap delegate() { return (SortedMap) super.delegate(); } @Override @CheckForNull public Comparator comparator() { synchronized (mutex) { return delegate().comparator(); } } @Override public K firstKey() { synchronized (mutex) { return delegate().firstKey(); } } @Override public SortedMap headMap(K toKey) { synchronized (mutex) { return sortedMap(delegate().headMap(toKey), mutex); } } @Override public K lastKey() { synchronized (mutex) { return delegate().lastKey(); } } @Override public SortedMap subMap(K fromKey, K toKey) { synchronized (mutex) { return sortedMap(delegate().subMap(fromKey, toKey), mutex); } } @Override public SortedMap tailMap(K fromKey) { synchronized (mutex) { return sortedMap(delegate().tailMap(fromKey), mutex); } } private static final long serialVersionUID = 0; } static BiMap biMap( BiMap bimap, @CheckForNull Object mutex) { if (bimap instanceof SynchronizedBiMap || bimap instanceof ImmutableBiMap) { return bimap; } return new SynchronizedBiMap<>(bimap, mutex, null); } @VisibleForTesting static class SynchronizedBiMap extends SynchronizedMap implements BiMap, Serializable { @CheckForNull private transient Set valueSet; @RetainedWith @CheckForNull private transient BiMap inverse; private SynchronizedBiMap( BiMap delegate, @CheckForNull Object mutex, @CheckForNull BiMap inverse) { super(delegate, mutex); this.inverse = inverse; } @Override BiMap delegate() { return (BiMap) super.delegate(); } @Override public Set values() { synchronized (mutex) { if (valueSet == null) { valueSet = set(delegate().values(), mutex); } return valueSet; } } @Override @CheckForNull public V forcePut(@ParametricNullness K key, @ParametricNullness V value) { synchronized (mutex) { return delegate().forcePut(key, value); } } @Override public BiMap inverse() { synchronized (mutex) { if (inverse == null) { inverse = new SynchronizedBiMap<>(delegate().inverse(), mutex, this); } return inverse; } } private static final long serialVersionUID = 0; } private static class SynchronizedAsMap extends SynchronizedMap> { @CheckForNull transient Set>> asMapEntrySet; @CheckForNull transient Collection> asMapValues; SynchronizedAsMap(Map> delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override @CheckForNull public Collection get(@CheckForNull Object key) { synchronized (mutex) { Collection collection = super.get(key); return (collection == null) ? null : typePreservingCollection(collection, mutex); } } @Override public Set>> entrySet() { synchronized (mutex) { if (asMapEntrySet == null) { asMapEntrySet = new SynchronizedAsMapEntries<>(delegate().entrySet(), mutex); } return asMapEntrySet; } } @Override public Collection> values() { synchronized (mutex) { if (asMapValues == null) { asMapValues = new SynchronizedAsMapValues(delegate().values(), mutex); } return asMapValues; } } @Override public boolean containsValue(@CheckForNull Object o) { // values() and its contains() method are both synchronized. return values().contains(o); } private static final long serialVersionUID = 0; } private static class SynchronizedAsMapValues extends SynchronizedCollection> { SynchronizedAsMapValues(Collection> delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override public Iterator> iterator() { // Must be manually synchronized. return new TransformedIterator, Collection>(super.iterator()) { @Override Collection transform(Collection from) { return typePreservingCollection(from, mutex); } }; } private static final long serialVersionUID = 0; } @GwtIncompatible // NavigableSet @VisibleForTesting static class SynchronizedNavigableSet extends SynchronizedSortedSet implements NavigableSet { SynchronizedNavigableSet(NavigableSet delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override NavigableSet delegate() { return (NavigableSet) super.delegate(); } @Override @CheckForNull public E ceiling(E e) { synchronized (mutex) { return delegate().ceiling(e); } } @Override public Iterator descendingIterator() { return delegate().descendingIterator(); // manually synchronized } @CheckForNull transient NavigableSet descendingSet; @Override public NavigableSet descendingSet() { synchronized (mutex) { if (descendingSet == null) { NavigableSet dS = Synchronized.navigableSet(delegate().descendingSet(), mutex); descendingSet = dS; return dS; } return descendingSet; } } @Override @CheckForNull public E floor(E e) { synchronized (mutex) { return delegate().floor(e); } } @Override public NavigableSet headSet(E toElement, boolean inclusive) { synchronized (mutex) { return Synchronized.navigableSet(delegate().headSet(toElement, inclusive), mutex); } } @Override public SortedSet headSet(E toElement) { return headSet(toElement, false); } @Override @CheckForNull public E higher(E e) { synchronized (mutex) { return delegate().higher(e); } } @Override @CheckForNull public E lower(E e) { synchronized (mutex) { return delegate().lower(e); } } @Override @CheckForNull public E pollFirst() { synchronized (mutex) { return delegate().pollFirst(); } } @Override @CheckForNull public E pollLast() { synchronized (mutex) { return delegate().pollLast(); } } @Override public NavigableSet subSet( E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { synchronized (mutex) { return Synchronized.navigableSet( delegate().subSet(fromElement, fromInclusive, toElement, toInclusive), mutex); } } @Override public SortedSet subSet(E fromElement, E toElement) { return subSet(fromElement, true, toElement, false); } @Override public NavigableSet tailSet(E fromElement, boolean inclusive) { synchronized (mutex) { return Synchronized.navigableSet(delegate().tailSet(fromElement, inclusive), mutex); } } @Override public SortedSet tailSet(E fromElement) { return tailSet(fromElement, true); } private static final long serialVersionUID = 0; } @GwtIncompatible // NavigableSet static NavigableSet navigableSet( NavigableSet navigableSet, @CheckForNull Object mutex) { return new SynchronizedNavigableSet(navigableSet, mutex); } @GwtIncompatible // NavigableSet static NavigableSet navigableSet(NavigableSet navigableSet) { return navigableSet(navigableSet, null); } @GwtIncompatible // NavigableMap static NavigableMap navigableMap( NavigableMap navigableMap) { return navigableMap(navigableMap, null); } @GwtIncompatible // NavigableMap static NavigableMap navigableMap( NavigableMap navigableMap, @CheckForNull Object mutex) { return new SynchronizedNavigableMap<>(navigableMap, mutex); } @GwtIncompatible // NavigableMap @VisibleForTesting static class SynchronizedNavigableMap extends SynchronizedSortedMap implements NavigableMap { SynchronizedNavigableMap(NavigableMap delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override NavigableMap delegate() { return (NavigableMap) super.delegate(); } @Override @CheckForNull public Map.Entry ceilingEntry(K key) { synchronized (mutex) { return nullableSynchronizedEntry(delegate().ceilingEntry(key), mutex); } } @Override @CheckForNull public K ceilingKey(K key) { synchronized (mutex) { return delegate().ceilingKey(key); } } @CheckForNull transient NavigableSet descendingKeySet; @Override public NavigableSet descendingKeySet() { synchronized (mutex) { if (descendingKeySet == null) { return descendingKeySet = Synchronized.navigableSet(delegate().descendingKeySet(), mutex); } return descendingKeySet; } } @CheckForNull transient NavigableMap descendingMap; @Override public NavigableMap descendingMap() { synchronized (mutex) { if (descendingMap == null) { return descendingMap = navigableMap(delegate().descendingMap(), mutex); } return descendingMap; } } @Override @CheckForNull public Map.Entry firstEntry() { synchronized (mutex) { return nullableSynchronizedEntry(delegate().firstEntry(), mutex); } } @Override @CheckForNull public Map.Entry floorEntry(K key) { synchronized (mutex) { return nullableSynchronizedEntry(delegate().floorEntry(key), mutex); } } @Override @CheckForNull public K floorKey(K key) { synchronized (mutex) { return delegate().floorKey(key); } } @Override public NavigableMap headMap(K toKey, boolean inclusive) { synchronized (mutex) { return navigableMap(delegate().headMap(toKey, inclusive), mutex); } } @Override public SortedMap headMap(K toKey) { return headMap(toKey, false); } @Override @CheckForNull public Map.Entry higherEntry(K key) { synchronized (mutex) { return nullableSynchronizedEntry(delegate().higherEntry(key), mutex); } } @Override @CheckForNull public K higherKey(K key) { synchronized (mutex) { return delegate().higherKey(key); } } @Override @CheckForNull public Map.Entry lastEntry() { synchronized (mutex) { return nullableSynchronizedEntry(delegate().lastEntry(), mutex); } } @Override @CheckForNull public Map.Entry lowerEntry(K key) { synchronized (mutex) { return nullableSynchronizedEntry(delegate().lowerEntry(key), mutex); } } @Override @CheckForNull public K lowerKey(K key) { synchronized (mutex) { return delegate().lowerKey(key); } } @Override public Set keySet() { return navigableKeySet(); } @CheckForNull transient NavigableSet navigableKeySet; @Override public NavigableSet navigableKeySet() { synchronized (mutex) { if (navigableKeySet == null) { return navigableKeySet = Synchronized.navigableSet(delegate().navigableKeySet(), mutex); } return navigableKeySet; } } @Override @CheckForNull public Map.Entry pollFirstEntry() { synchronized (mutex) { return nullableSynchronizedEntry(delegate().pollFirstEntry(), mutex); } } @Override @CheckForNull public Map.Entry pollLastEntry() { synchronized (mutex) { return nullableSynchronizedEntry(delegate().pollLastEntry(), mutex); } } @Override public NavigableMap subMap( K fromKey, boolean fromInclusive, K toKey, boolean toInclusive) { synchronized (mutex) { return navigableMap(delegate().subMap(fromKey, fromInclusive, toKey, toInclusive), mutex); } } @Override public SortedMap subMap(K fromKey, K toKey) { return subMap(fromKey, true, toKey, false); } @Override public NavigableMap tailMap(K fromKey, boolean inclusive) { synchronized (mutex) { return navigableMap(delegate().tailMap(fromKey, inclusive), mutex); } } @Override public SortedMap tailMap(K fromKey) { return tailMap(fromKey, true); } private static final long serialVersionUID = 0; } @GwtIncompatible // works but is needed only for NavigableMap @CheckForNull private static Map.Entry nullableSynchronizedEntry( @CheckForNull Map.Entry entry, @CheckForNull Object mutex) { if (entry == null) { return null; } return new SynchronizedEntry<>(entry, mutex); } @GwtIncompatible // works but is needed only for NavigableMap private static class SynchronizedEntry extends SynchronizedObject implements Map.Entry { SynchronizedEntry(Map.Entry delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @SuppressWarnings("unchecked") // guaranteed by the constructor @Override Map.Entry delegate() { return (Map.Entry) super.delegate(); } @Override public boolean equals(@CheckForNull Object obj) { synchronized (mutex) { return delegate().equals(obj); } } @Override public int hashCode() { synchronized (mutex) { return delegate().hashCode(); } } @Override public K getKey() { synchronized (mutex) { return delegate().getKey(); } } @Override public V getValue() { synchronized (mutex) { return delegate().getValue(); } } @Override public V setValue(V value) { synchronized (mutex) { return delegate().setValue(value); } } private static final long serialVersionUID = 0; } static Queue queue(Queue queue, @CheckForNull Object mutex) { return (queue instanceof SynchronizedQueue) ? queue : new SynchronizedQueue(queue, mutex); } private static class SynchronizedQueue extends SynchronizedCollection implements Queue { SynchronizedQueue(Queue delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override Queue delegate() { return (Queue) super.delegate(); } @Override public E element() { synchronized (mutex) { return delegate().element(); } } @Override public boolean offer(E e) { synchronized (mutex) { return delegate().offer(e); } } @Override @CheckForNull public E peek() { synchronized (mutex) { return delegate().peek(); } } @Override @CheckForNull public E poll() { synchronized (mutex) { return delegate().poll(); } } @Override public E remove() { synchronized (mutex) { return delegate().remove(); } } private static final long serialVersionUID = 0; } static Deque deque(Deque deque, @CheckForNull Object mutex) { return new SynchronizedDeque(deque, mutex); } private static final class SynchronizedDeque extends SynchronizedQueue implements Deque { SynchronizedDeque(Deque delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @Override Deque delegate() { return (Deque) super.delegate(); } @Override public void addFirst(E e) { synchronized (mutex) { delegate().addFirst(e); } } @Override public void addLast(E e) { synchronized (mutex) { delegate().addLast(e); } } @Override public boolean offerFirst(E e) { synchronized (mutex) { return delegate().offerFirst(e); } } @Override public boolean offerLast(E e) { synchronized (mutex) { return delegate().offerLast(e); } } @Override public E removeFirst() { synchronized (mutex) { return delegate().removeFirst(); } } @Override public E removeLast() { synchronized (mutex) { return delegate().removeLast(); } } @Override @CheckForNull public E pollFirst() { synchronized (mutex) { return delegate().pollFirst(); } } @Override @CheckForNull public E pollLast() { synchronized (mutex) { return delegate().pollLast(); } } @Override public E getFirst() { synchronized (mutex) { return delegate().getFirst(); } } @Override public E getLast() { synchronized (mutex) { return delegate().getLast(); } } @Override @CheckForNull public E peekFirst() { synchronized (mutex) { return delegate().peekFirst(); } } @Override @CheckForNull public E peekLast() { synchronized (mutex) { return delegate().peekLast(); } } @Override public boolean removeFirstOccurrence(@CheckForNull Object o) { synchronized (mutex) { return delegate().removeFirstOccurrence(o); } } @Override public boolean removeLastOccurrence(@CheckForNull Object o) { synchronized (mutex) { return delegate().removeLastOccurrence(o); } } @Override public void push(E e) { synchronized (mutex) { delegate().push(e); } } @Override public E pop() { synchronized (mutex) { return delegate().pop(); } } @Override public Iterator descendingIterator() { synchronized (mutex) { return delegate().descendingIterator(); } } private static final long serialVersionUID = 0; } static Table table(Table table, @CheckForNull Object mutex) { return new SynchronizedTable<>(table, mutex); } private static final class SynchronizedTable< R extends @Nullable Object, C extends @Nullable Object, V extends @Nullable Object> extends SynchronizedObject implements Table { SynchronizedTable(Table delegate, @CheckForNull Object mutex) { super(delegate, mutex); } @SuppressWarnings("unchecked") @Override Table delegate() { return (Table) super.delegate(); } @Override public boolean contains(@CheckForNull Object rowKey, @CheckForNull Object columnKey) { synchronized (mutex) { return delegate().contains(rowKey, columnKey); } } @Override public boolean containsRow(@CheckForNull Object rowKey) { synchronized (mutex) { return delegate().containsRow(rowKey); } } @Override public boolean containsColumn(@CheckForNull Object columnKey) { synchronized (mutex) { return delegate().containsColumn(columnKey); } } @Override public boolean containsValue(@CheckForNull Object value) { synchronized (mutex) { return delegate().containsValue(value); } } @Override @CheckForNull public V get(@CheckForNull Object rowKey, @CheckForNull Object columnKey) { synchronized (mutex) { return delegate().get(rowKey, columnKey); } } @Override public boolean isEmpty() { synchronized (mutex) { return delegate().isEmpty(); } } @Override public int size() { synchronized (mutex) { return delegate().size(); } } @Override public void clear() { synchronized (mutex) { delegate().clear(); } } @Override @CheckForNull public V put( @ParametricNullness R rowKey, @ParametricNullness C columnKey, @ParametricNullness V value) { synchronized (mutex) { return delegate().put(rowKey, columnKey, value); } } @Override public void putAll(Table table) { synchronized (mutex) { delegate().putAll(table); } } @Override @CheckForNull public V remove(@CheckForNull Object rowKey, @CheckForNull Object columnKey) { synchronized (mutex) { return delegate().remove(rowKey, columnKey); } } @Override public Map row(@ParametricNullness R rowKey) { synchronized (mutex) { return map(delegate().row(rowKey), mutex); } } @Override public Map column(@ParametricNullness C columnKey) { synchronized (mutex) { return map(delegate().column(columnKey), mutex); } } @Override public Set> cellSet() { synchronized (mutex) { return set(delegate().cellSet(), mutex); } } @Override public Set rowKeySet() { synchronized (mutex) { return set(delegate().rowKeySet(), mutex); } } @Override public Set columnKeySet() { synchronized (mutex) { return set(delegate().columnKeySet(), mutex); } } @Override public Collection values() { synchronized (mutex) { return collection(delegate().values(), mutex); } } @Override public Map> rowMap() { synchronized (mutex) { return map( Maps.transformValues( delegate().rowMap(), new com.google.common.base.Function, Map>() { @Override public Map apply(Map t) { return map(t, mutex); } }), mutex); } } @Override public Map> columnMap() { synchronized (mutex) { return map( Maps.transformValues( delegate().columnMap(), new com.google.common.base.Function, Map>() { @Override public Map apply(Map t) { return map(t, mutex); } }), mutex); } } @Override public int hashCode() { synchronized (mutex) { return delegate().hashCode(); } } @Override public boolean equals(@CheckForNull Object obj) { if (this == obj) { return true; } synchronized (mutex) { return delegate().equals(obj); } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy