I have a thread safe class Container:
public class Container {
private int x;
...
public synchronized int getX();
public synchronized void setX(int x);
}
Then I have a list of containers:
List<Container> containers;
I would like to iterate through the list, aquire the container's lock at each iteration and, only at the end of loop, release all locks. Something like this:
for(Container c : containers) {
c.lock();
//do stuff
}
for(Container c : containers)
c.unlock();
I still want other threads to be able to continue to use getX and setX methods of unlocked containers, but for various reasons I do not want to allow that for already analysed containers.
Do you know the java code for that?
Better ideas are also appreciated.
This is not possible I'm afraid. The Java Language imposes a strict nesting principle with the synchronized (...) { ... }
blocks (and synchronized methods).
That being said, there are nasty workarounds. In bytecode a synchronized block translates to two separate monitorenter
/ monitorexit
instructions. The same thing can be achieved with sun.mis.Unsafe.monitorEnter()
and monitorExit()
.
In this case however, I would strongly encourage you to rethink the design. I would suggest you let getX
and setX
acquire / release an internal Lock
(which the traversal method also uses). In particular, you could use ReadWriteLock
for your setX
and getX
methods. In fact, this approach is better than having synchronized
methods for other reasons too. See for instance:
Why is it a good practice to have separate locks instead of having lock on object that get modified in the synchronized block in java?
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