Java将显式锁与同步方法相结合
我有一个线程安全类容器:Java将显式锁与同步方法相结合,java,multithreading,concurrency,synchronization,locking,Java,Multithreading,Concurrency,Synchronization,Locking,我有一个线程安全类容器: public class Container { private int x; ... public synchronized int getX(); public synchronized void setX(int x); } 然后我有一个容器列表: List<Container> containers; 我仍然希望其他线程能够继续使用未锁定容器的getX和setX方法,但出于各种原因,我不希望允许已经分析过的容器使用这些方法。 您知
public class Container {
private int x;
...
public synchronized int getX();
public synchronized void setX(int x);
}
然后我有一个容器列表:
List<Container> containers;
我仍然希望其他线程能够继续使用未锁定容器的getX和setX方法,但出于各种原因,我不希望允许已经分析过的容器使用这些方法。
您知道这方面的java代码吗?
更好的想法也会受到赞赏。恐怕这是不可能的。Java语言对
synchronized(…){…}
块(和synchronized方法)施加了严格的嵌套原则
尽管如此,还是有一些令人讨厌的变通办法。在字节码中,同步块转换为两条独立的monitorenter
/monitorexit
指令。使用sun.mis.Unsafe.monitorEnter()和monitorExit()也可以实现同样的效果
但是,在这种情况下,我强烈建议您重新考虑设计。我建议您让getX
和setX
获取/释放内部文件(遍历方法也使用该文件)。特别是,您可以使用setX
和getX
方法。事实上,由于其他原因,这种方法也比使用同步的方法要好。例如,见:
在getX
和setX
中的lock()
和unlock()
第一个和最后一个如何?@请看@aioobe:我想将同步方法与显式锁结合起来(希望这是可能的,但我认为这是因为在幕后同步关键字获得了对象锁)@Lance Java:但在我的例子中,你会如何在for循环中使用try finally?也许尝试一下所有的for循环,最后释放所有的锁?解锁未锁定的锁可以吗?关于不同的方法:如果您解释如何使用容器,那么使用不可变容器的解决方案可能会更好…synchronized关键字不获取对象本身的锁吗?这就像在方法中写入synchronized(this){}。如果我们锁定这个,为什么我们不能创建一个锁定对象的锁(这个)?使用内部锁,我不会有同样的问题吗?如何在不使用synchronized关键字的情况下获取多个内部锁(每次迭代一个锁)?您的理解是正确的。唯一的原因是我们不能只做一些像锁(这个)代码>然后稍后<代码>解锁(此)
(对应于synchronized(this)
)的开始大括号{
和结束大括号}
),获取此类锁的唯一方法是通过synchronized关键字(除非您采用我在回答中提到的不安全操作)synchronized关键字具有{…}
块的语法约束。不,对于内部锁,您可以使用lock
,它具有单独的lock()
和unlock()
方法!(答案更新)谢谢,但是我如何在for循环中编写try finally块呢?我的意思是最后我应该解锁所有的锁吗?
for(Container c : containers) {
c.lock();
//do stuff
}
for(Container c : containers)
c.unlock();