简体   繁体   中英

Java combine explicit locks with synchronized methods

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM