I need to lock two objects in a functionality and the current code looke like this;
Object obj1 = ...//get from somewhere
Object obj2 = ...//get from somewhere
synchronized(obj1){
...//blah
synchronized(obj2){
...//blah
}
}
As you can see this is a plain and straight recipe for deadlocks if another thread runs this piece of code with obj1 and two reversed.
Is there a way to avoid this situation using concurrency-utils locks?
I was contemplating maintaining a map of objects and their locks and verifying if they were available to take, but can't seem to come up with a clean way which will predict the lock order.
Depending on what you are doing you may be able to take what you want from the first locked object and use that information to process the second locked object. e.g.
instead of
do this
You can see you only have lock at a time so you won't get a deadlock.
You can solve it in other way I suppose.
Then do
And use it as you want:
Although you preserve locking order, if obj1 is switched with obj2 you'll run into deadlock.
You must look for another solution to avoid this cases: lock ordering + optional tie breaking lock
You need to consistently lock in the order of obj1 and then obj2. If you never violate this order, you won't have deadlocks.
Essentially what you have is the dining philospher's problem.
https://en.wikipedia.org/wiki/Dining_philosophers_problem
Ovidiu Lupas's answer is similar to Dijkstra's Resource Heirarchy solution, but there are 3 more solutions, explained on the wiki page
This is what the arbitrator solution looks like. If all of the objects which you're operating from inherit from the same type, you could use static class variables to implement the arbitrators on the class of objects.
The Chandy/Misra solution requires a lot of message passing so I'm not going to implement it, but wikipedia has a pretty good explaination