android/guava/src/com/google/common/collect/Maps.java
public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
    return Synchronized.biMap(bimap, null);
  }
public static <K, V> BiMap<K, V> synchronizedBiMap(BiMap<K, V> bimap) {
    return Synchronized.biMap(bimap, null);
  }
Returns a synchronized (thread-safe) bimap backed by the specified bimap. In order to guarantee
serial access, it is critical that <b>all</b> access to the backing bimap is accomplished
through the returned bimap.

<p>It is imperative that the user manually synchronize on the returned map when accessing any
of its collection views:

<pre>{@code
BiMap<Long, String> map = Maps.synchronizedBiMap(
HashBiMap.<Long, String>create());
...
Set<Long> set = map.keySet();  // Needn't be in synchronized block
...
synchronized (map) {  // Synchronizing on map, not set!
Iterator<Long> it = set.iterator(); // Must be in synchronized block
while (it.hasNext()) {
foo(it.next());
}
}
}</pre>

<p>Failure to follow this advice may result in non-deterministic behavior.

<p>The returned bimap will be serializable if the specified bimap is serializable.

@param bimap the bimap to be wrapped in a synchronized view
@return a synchronized view of the specified bimap