What is the best way to prevent concurrent update of one record in a key-value set without locking the entire set? Semantically, I'm looking for some kind of locking by a key (ideally, Java implementation, but not necessarily):
interface LockByKey {
void lock(String key); // acquire an exclusive lock for a key
void unlock(String key); // release lock for a key
}
This lock is intended to synchronize an access to a remote store, so some synchronized Java collection is not an option.
Guava has something like this being released in 13.0; you can get it out of HEAD if you like.
Striped<Lock>
more or less allocates a specific number of locks, and then assigns strings to locks based on their hash code. The API looks more or less like
Striped<Lock> locks = Striped.lock(stripes);
Lock l = locks.get(string);
l.lock();
try {
// do stuff
} finally {
l.unlock();
}
More or less, the controllable number of stripes lets you trade concurrency against memory usage, because allocating a full lock for each string key can get expensive; essentially, you only get lock contention when you get hash collisions, which are (predictably) rare.
(Disclosure: I contribute to Guava.)