Java combines explicit locks with synchronized methods

I have a class protected by the Container stream:

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 scroll through the list, grab the container lock at each iteration and, only at the end of the loop, release all the locks. Something like that:

 for(Container c : containers) { c.lock(); //do stuff } for(Container c : containers) c.unlock(); 

I still want other threads to continue to use the getX and setX methods of unlocked containers, but for various reasons, I don’t want to allow this for containers already analyzed.

Do you know Java code for this?

Best ideas are also welcome.

+5
source share
1 answer

This is impossible, I'm afraid. The Java language imposes a strict nesting principle with synchronized (...) { ... } blocks (and synchronized methods).

That being said, there are unpleasant workarounds. In bytecode, the synchronized block is converted to two separate monitorenter / monitorexit . You can do the same with sun.mis.Unsafe.monitorEnter() and monitorExit() .

In this case, however, I highly recommend that you review the design. I suggest you let getX and setX acquire / release internal Lock (which also uses a workaround). In particular, you can use ReadWriteLock for your setX and getX . This approach is actually better than using synchronized methods for other reasons. See for example:

Why is it good practice to have separate locks instead of object locks that are modified in a synchronized block in java?

+1
source

All Articles