【问题标题】:Acquiring inner-class lock using outer-class locks?使用外部锁获取内部锁?
【发布时间】:2013-09-14 13:25:13
【问题描述】:

我有一个外部类A,它有一个公共内部类,结构如下-:

public class A{

      public int x;

      public class B{
        private static final int y;
      }

      public synchronized int method1(){
             return x+ B.y;
      }
}

问题是如果我在类 A 的每个方法上都使用了 synchronized 关键字,它是否也会锁定内部类的成员?

【问题讨论】:

    标签: java multithreading concurrency


    【解决方案1】:

    如果我在类 A 的每个方法上都使用了 synchronized 关键字,它是否也会锁定内部类的成员?

    不会的。

    您似乎在很多方面都感到困惑。

    • 使用原始互斥锁(例如通过synchronized 方法)锁定在相同互斥锁上同步的其他线程。

    • 当您调用同步实例方法时,您获取的互斥锁是this ...目标对象的互斥锁。

    • 在您的示例中,您似乎想锁定 static 字段,而不是实例字段。


    如果我正确理解您要做什么,那么正确的做法是这样的:

     public synchronized int method1(){
         synchronized (B.class) {
             return x + B.y;
         }
     }
    

    请注意,这涉及获取 两个 互斥体,因此您需要确保您的代码始终以相同的顺序获取它们。 (如果不这样做,就会有死锁的风险。)

    如果您在B 上创建并调用同步静态方法以获取y 字段的值,您将获得相同的效果。

    【讨论】:

    • 实际上我正在解决粗粒度锁定链表数据结构的问题,其中我具有以下结构 - 类 LList{ public class Node{} public class InsertNode{}} 和当一个线程假设 T1 在链表数据结构上获得了锁,我想确保没有其他线程在列表中的各个节点上获得锁,也不在列表数据结构上我如何确保发生这种情况。
    • @AnkitSablok - 如上所述。使用两个对象作为互斥体。
    【解决方案2】:

    不,内部类和外部类是两个不同的类对象,它们不会相同。我建议在外部类中创建一个字段以手动同步。

    【讨论】:

    • 你能举个例子吗?
    【解决方案3】:

    在 2 个对象上使用单个互斥锁的示例。两个对象都可以更改变量 x。

    公共类 A { 私有对象互斥=新对象(); 私人int x; 私人 B b = 新 B(); 公共类 B { 私人int y; 公共 int 方法() { 同步(互斥){ 返回 x++; } } } 公共 int 方法() { 同步(互斥){ 返回 x += b.y; } } }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-20
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 2018-12-09
      • 1970-01-01
      相关资源
      最近更新 更多