Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to acquire a lock by a key

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.

like image 537
user1128016 Avatar asked Jun 20 '12 17:06

user1128016


People also ask

Can you make a lock from a key?

Yes, an experienced locksmith should generally have the ability to make a lock from a key. However, it is important to remember that the steps involved in this process can be challenging for even experienced locksmiths and may require some patience on the part of the client or customer.

What does it mean to acquire a lock?

Acquiring a lock allows a thread to have exclusive access to the data guarded by that lock, forcing other threads to block — as long as those threads are also trying to acquire that same lock. The monitor pattern guards the rep of a datatype with a single lock that is acquired by every method.

How can we acquire lock on class?

class as a parameter tells which class has to synchronized at the class level. As soon as the thread entered the synchronized block, the thread acquire the lock at class, rest of the threads wait to get the class monitor lock. The thread will leave lock when it exits from the synchronized block.

Can you get a key cut for a lock without a key?

If it's a lost key a locksmith can make you a key without the original, as locksmiths can make keys to lock by hand. By using a blank and a file and the skills, they've developed over the years a locksmith can create a key from scratch without the need for an original key.


2 Answers

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.)

like image 161
Louis Wasserman Avatar answered Sep 18 '22 13:09

Louis Wasserman


private static final Set<String> lockedKeys = new HashSet<>();  private void lock(String key) throws InterruptedException {     synchronized (lockedKeys) {         while (!lockedKeys.add(key)) {             lockedKeys.wait();         }     } }  private void unlock(String key) {     synchronized (lockedKeys) {         lockedKeys.remove(key);         lockedKeys.notifyAll();     } }  public void doSynchronously(String key) throws InterruptedException {     try {         lock(key);          //Do what you need with your key.         //For different keys this part is executed in parallel.         //For equal keys this part is executed synchronously.      } finally {         unlock(key);     } } 

try-finally - is very important - you must guarantee to unlock waiting threads after your operation even if your operation threw exception.

like image 25
Anton Fil Avatar answered Sep 18 '22 13:09

Anton Fil