[英]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.