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()
.
可以实现相同的目的
但是,在这种情况下,我强烈建议您重新考虑设计。我建议您让 getX
和 setX
为您的 setX
和 getX
方法获取/释放内部 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?
我有一个线程安全的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()
.
但是,在这种情况下,我强烈建议您重新考虑设计。我建议您让 getX
和 setX
为您的 setX
和 getX
方法获取/释放内部 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?