Reputation: 191
I have a class that is accessed by multiple threads, and I want to make sure it's thread safe. Plus it needs to be as fast as possible. This is just an example:
public class SharedClass {
private final Map<String, String> data = new HashMap<>();
private final Striped<ReadWriteLock> rwLockStripes = Striped.readWriteLock(100);
public void setSomethingFastVersion(String key, String value) {
ReadWriteLock rwLock = rwLockStripes.get(key);
try {
rwLock.lock();
} finally{
rwLock.unLock();
}
data.put(key, value);
}
public synchronized void setSomethingSlowVersion(String key, String value) {
data.put(key, value);
}
}
I'm using StripedLock
from Google Guava in one version, and a normal synchronized
on the other one.
Am I right saying that the Guava version should be faster?
If so, what would be a good use case for synchronized
, where the StripedLocks
would not fit?
BTW, I know I could use a simple ConcurrentHashMap
here, but I'm adding the example code to make sure you understand my question.
Upvotes: 10
Views: 6244
Reputation: 1636
Let me put in this way. Say you have 1000 instances of a class, and you have 1000 threads trying to accesses those instances. Each instance will acquire a lock for each thread. So 1000 locks which will lead to huge memory consumption. In this case stripped locks could come handy.
But in normal case where you have a singleton class you may not need stripped locks and can go ahead and use synchronized keyword.
So, i hope i answered when to use what.
Upvotes: 0
Reputation: 73558
Synchronized has been around for ages. It's not really surprising that we nowadays have more advanced mechanisms for concurrent programming.
However striped locks are advantageous only in cases where something can be partitioned or striped, such as locking parts of a map allowing different parts to be manipulated at the same time, but blocking simultaneous manipulations to the same stripe. In many cases you don't have that kind of partitioning, you're just looking for a mutex. In those cases synchronized
is still a viable option, although a ReadWriteLock
might be a better choice depending on the situation.
A ConcurrentHashMap
has internal partitioning similar to stripes, but it applies only to the map operations such as put()
. With an explicit StripedLock
you can make longer operations atomic, while still allowing concurrency when operations don't touch the same stripe.
Upvotes: 7
Reputation: 2756
Use a ConcurrentHashMap
so you won't have to do any of your own synchronizing.
Upvotes: -2