我有一个线程安全类容器:
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 (...) { ... }
block (和同步方法)施加了严格的嵌套原则。
话虽这么说,但还是有一些糟糕的解决方法。在 bytecode 中,同步块(synchronized block)转换为两个单独的 monitorenter
/monitorexit
指令。使用 sun.mis.Unsafe.monitorEnter()
和 monitorExit()
也可以达到同样的效果。
但是,在这种情况下,我强烈建议您重新考虑设计。我建议您让 getX
和 setX
获取/释放内部 Lock
(遍历方法也使用)。特别是,您可以使用 ReadWriteLock
对于您的 setX
和 getX
方法。事实上,出于其他原因,这种方法也比使用 synchronized
方法要好。参见示例:
关于Java 将显式锁与同步方法结合起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30798558/