繁体   English   中英

从 Java 中的匿名内部 class 调用外部同步方法

[英]Call outer synchronized method from anonymous inner class in Java

从匿名内部 class 调用同步方法是否安全且正确? 外部 class 中的锁定监视器是否正确获取?

这是代码的一小部分摘录,显示了我的意思。

留下这样的代码是否有任何问题,或者我最好更改它?

class OuterClass {

   public synchronized Object getValue(String id) { .... }

   public synchronized getValueFunction(String id) {
      
      return new GetValueInnerInterface() {
          @Override
          public Object getValueInner(String id) {
              return getValue(id);
          }
      }      
   } 

}

谢谢

synchronized void foo() {
  code();
}

只是语法糖。 这与以下内容完全相同:

void foo() {
  synchronized (this) {
    code();
  }
}

如果foo是 static,并且在名为class Example {}的 class 中,它是:

static void foo() {
  synchronized (Example.class) {
    code();
  }
}

因此,这意味着将“同步”放在方法上几乎总是错误的。 锁是重要的东西,如果你“泄露”它们,那么你需要记录你的锁定行为。 通常,您希望您的锁是私有的,这意味着正确的举动通常是:

public class Example {
  private final Object locker = new Object();

  public void doSomethingSynchronized() {
    synchronized (locker) {
      code();
    }
  }
}

但是,如果你真的想用公共锁 go (鉴于Example.class是其他不受你控制的代码也可以锁定,通常, this也可用于你直接控制之外的代码),然后确保记录它,这也意味着您必须继续支持锁定行为,因为您将永远记录它(好吧,或者破坏向后兼容性)。

鉴于这是它的工作原理,是的,当然,如果您从匿名内部 class 或其他任何地方调用这些方法,它们将锁定在具有synchronized关键字的方法的上下文中this意味着什么(因此,外部的实例,而不是内部的实例)。

请注意,在getValueFunction方法上粘贴synchronized似乎没用:这个 function 不需要同步,如所写。

此外,一般来说,“只是将同步关键字扔到任何地方,就像它已经过时一样”是实现线程安全的一种非常糟糕的方式(例如,它实际上不会给你线程安全并减慢一切速度)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM