Java 将显式锁与同步方法相结合

Java combine explicit locks with synchronized methods

我有一个线程安全的class容器:

public class Container {
  private int x;
  ...
  public synchronized int getX();
  public synchronized void setX(int x);
}

然后我有一个容器列表:

List<Container> containers;

我想遍历列表,在每次迭代时获取容器的锁,并且仅在循环结束时释放所有锁。 像这样:

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

我仍然希望其他线程能够继续使用已解锁容器的 getX 和 setX 方法,但出于各种原因我不想让已经分析过的容器这样做。

你知道 java 代码吗?

也欢迎更好的想法。

恐怕这是不可能的。 Java 语言对 synchronized (...) { ... } 块(和同步方法)施加了严格的嵌套原则。

话虽这么说,但还是有一些糟糕的解决方法。在 字节码 中,同步块转换为两个单独的 monitorenter / monitorexit 指令。使用 sun.mis.Unsafe.monitorEnter()monitorExit().

可以实现相同的目的

但是,在这种情况下,我强烈建议您重新考虑设计。我建议您让 getXsetX 为您的 setXgetX 方法获取/释放内部 Lock (which the traversal method also uses). In particular, you could use ReadWriteLock。事实上,出于其他原因,这种方法也比使用 synchronized 方法要好。例如参见:

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?