I am currently using Guava Multimap implementation.
map = Multimaps.synchronizedSetMultimap(HashMultimap.<K, R> create());
However I found that my program performance is now bounded by the synchronization block synchronized (mutex)
used in Multimaps.synchronizedSetMultimap
.
Therefore I am finding if there are ANY alternatives to have a synchronized multimap, which hopefully can help improve program performance in multi-threading environment.
I don't mind if extra restrictions are imposed, like only one thread for updating (create, modify or removal), as long as I can read multimap data using multiple threads and at the same time, allow write operation. In addition, for my project usage, I would mostly read data (>99% if time) and seldom write data (< 1%), so I do not care too much on writing performance when compared to read performance).
From High-performance Concurrent MultiMap Java/Scala, someone suggest use of
Multimaps.newSetMultimap(new ConcurrentHashMap<>(), ConcurrentHashMap::newKeySet)
and since I am using Java 7, I convert the above code as follows:
map = Multimaps.newSetMultimap(new ConcurrentHashMap<K, Collection<R>>(), new Supplier<Set<R>>() {
public Set<R> get() {
return Sets.newSetFromMap(new ConcurrentHashMap<R, Boolean>());
}
});
which seems working really well. But again from the documentation, it states the following:
The multimap is not threadsafe when any concurrent operations update the multimap, even if map and the instances generated by factory are. Concurrent read operations will work correctly. To allow concurrent update operations, wrap the multimap with a call to synchronizedSetMultimap(com.google.common.collect.SetMultimap<K, V>).
However I have created a test code for concurrent read write, and it seems that it works (without any exceptions like ConcurrentModificationException). My current Java version is Java 7 and using Guava 14.0.1.
So my question is,
Multimaps.newSetMultimap(new ConcurrentHashMap<>(), ConcurrentHashMap::newKeySet)
fails to work properly? Or it simply just works accidentally with ConcurrentHashMap
?Many thanks.
The returned multimap is not thread-safe or serializable, even if the underlying multimap is.
A Multimap is a new collection type that is found in Google's Guava library for Java. A Multimap can store more than one value against a key. Both the keys and the values are stored in a collection, and considered to be alternates for Map<K, List<V>> or Map<K, Set<V>> (standard JDK Collections Framework).
A workaround for using HashMap in multi-threaded environment is to initialize it with the expected number of objects' count, hence avoiding the need for a re-sizing. Thanks for contributing an answer to Stack Overflow!
Multimap in C++ Standard Template Library (STL) Multimap is similar to map with an addition that multiple elements can have same keys. Rather than each element being unique, the key value and mapped value pair has to be unique in this case.
Internally, a multimap is implemented as a red-black tree. Each element of a multimap is treated as a pair. The first value is referred to as key and the second value is referred to as value. Multimap is quite similar to a map but in the case of a multimap, we can have multiple same keys.
Each element of a multimap is treated as a pair. The first value is referred to as key and the second value is referred to as value. Multimap is quite similar to a map but in the case of a multimap, we can have multiple same keys. Also, we cannot use square brackets ( []) to access the value mapped with a key.
You could use:
ConcurrentMap<K, CopyOnWriteArraySet<V>> multimap = new ConcurrentHashMap<>();
You could implement:
class ConcurrentArraySetMultimap<K, V> implements SetMultimap<K, V> {
on top of it.
If the Javadoc states Multimaps.newSetMultimap()
is not thread-safe, I would not try to prove it wrong. I looked at the implementation, and the reason likely is that additional logic is run on top of the decorated Map
and Set
.
However I have created a test code for concurrent read write, and it seems that it works (without any exceptions like ConcurrentModificationException)."
You can't really test thread-safety. Thread-safety bugs don't always happen -- they happen only sometimes, and they are extremely confusing when they do.
As linked by Xaerxess in the comments, there is no real way to support the entire Multimap
interface concurrently with decent performance. The solution instead is not to use the Multimap interface, but to have your own ConcurrentMap<K, Set<V>>
and be very, very careful. (This will be considerably harder in Java 7, with the more restricted ConcurrentMap
interface without atomic update operations.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With