I'm looking for a way to synchronize a method based on the parameter it receives, something like this:
public synchronized void doSomething(name){ //some code }
I want the method doSomething
to be synchronized based on the name
parameter like this:
Thread 1: doSomething("a");
Thread 2: doSomething("b");
Thread 3: doSomething("c");
Thread 4: doSomething("a");
Thread 1 , Thread 2 and Thread 3 will execute the code without being synchronized , but Thread 4 will wait until Thread 1 has finished the code because it has the same "a" value.
Thanks
UPDATE
Based on Tudor explanation I think I'm facing another problem: here is a sample of the new code:
private HashMap locks=new HashMap(); public void doSomething(String name){ locks.put(name,new Object()); synchronized(locks.get(name)) { // ... } locks.remove(name); }
The reason why I don't populate the locks map is because name can have any value.
Based on the sample above , the problem can appear when adding / deleting values from the hashmap by multiple threads in the same time, since HashMap is not thread-safe.
So my question is if I make the HashMap
a ConcurrentHashMap
which is thread safe, will the synchronized block stop other threads from accessing locks.get(name) ??
If a thread wants to execute a synchronized method on a given object, first it has to get a lock of that object. Once thread got the lock then it is allowed to execute any synchronized method on that object.
When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception.
Major difference between lock and synchronized: with locks, you can release and acquire the locks in any order. with synchronized, you can release the locks only in the order it was acquired.
Simply put, a lock is a more flexible and sophisticated thread synchronization mechanism than the standard synchronized block. The Lock interface has been around since Java 1.5. It's defined inside the java. util. concurrent.
Use a map to associate strings with lock objects:
Map<String, Object> locks = new HashMap<String, Object>(); locks.put("a", new Object()); locks.put("b", new Object()); // etc.
then:
public void doSomething(String name){ synchronized(locks.get(name)) { // ... } }
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