【问题标题】:Locking multiple objects in Java在 Java 中锁定多个对象
【发布时间】:2017-12-13 08:26:21
【问题描述】:

我有一种情况,在类 2 的多个实例中,一个操作会导致两者的状态发生变化,因为这是一个多线程应用程序,我想确保除非执行该特定代码,否则没有试图访问上述 2 个实例中的任何一个的其他线程处于等待状态。 使用 synchronized 或 lock 我们可以在单个实例上获取锁并将同步块嵌套在 2 个对象上也不是一个好主意。

synchronized(obj1){
 synchronized(obj2){
 }
}

另一个潜在的问题是,即使内部对象 obj2 是空闲的,由于外部对象被锁定,线程也会一直等待。 解决此问题的最佳方法可能是什么。

【问题讨论】:

  • “将同步块嵌套在 2 个对象上也不是一个好主意。”为什么不?你有什么样的代码路径?毕竟你想避免死锁,所以即使obj2 是免费的,如果obj1 不是免费的也没关系。
  • 如果再有类似sync(obj2) { sync(obj1) {...} }的代码就麻烦了
  • 为什么需要这样做?它们是否也独立锁定?我建议使用Lock - 并在访问对象之前始终锁定它。此外,使用Lock,您可以使用tryLock,从而防止死锁——在您必须按顺序获取锁的情况下。
  • 是的,所以如果基本上以对象的相反顺序进行操作,它可能会陷入死锁
  • 是的,那会是个问题,所以解决办法是确保没有这样的代码。你的问题?

标签: java multithreading locking synchronized


【解决方案1】:

当两个不同的线程以不同的顺序获取锁时,嵌套锁会带来死锁的风险。

没有消除此类死锁的通用方法。可能的解决方案包括:

  1. 维护锁对象的总顺序,并且仅按对象的升序(或仅按降序)获取锁。

    这是一种很好的解决方案,适用于以下情况:两个要锁定的对象都是已知的,而无需锁定其中一个对象。

  2. 使用tryLock 机制进行内锁。

    tryLock 如果对象已被其他线程锁定,则立即返回 false。所以程序应该以某种方式处理这种情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多