java - 从Java中的匿名内部类调用外部同步方法
问题描述
从匿名内部类调用同步方法是否安全且正确?外部类中的锁监视器是否正确获取?
这是代码的一小部分摘录,显示了我的意思。
留下这样的代码是否有任何问题,或者我最好更改它?
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
是静态的,在一个名为 的类中class Example {}
,它是:
static void foo() {
synchronized (Example.class) {
code();
}
}
因此,这意味着将“同步”放在方法上几乎总是错误的。锁是重要的东西,如果你“泄露”它们,那么你需要记录你的锁定行为。通常,您希望您的锁是私有的,这意味着正确的举动通常是:
public class Example {
private final Object locker = new Object();
public void doSomethingSynchronized() {
synchronized (locker) {
code();
}
}
}
但是,如果您真的想使用公共锁(假设Example.class
其他代码不受您控制也可以锁定,并且通常this
也可用于您直接控制之外的代码),然后确保记录它,这也意味着您必须继续支持锁定行为,因为您永远记录它(嗯,那个,或者破坏向后兼容性)。
鉴于这是它的工作方式,是的,当然,如果您从匿名内部类或其他任何地方调用这些方法,它们将锁定在具有关键字的方法的上下文中this
意味着什么(所以,外部的实例,而不是内部的实例)。synchronized
请注意,synchronized
在getValueFunction
方法上粘贴 a 似乎没用:该函数所做的任何事情都不需要同步,正如所写的那样。
此外,一般来说,“只是将同步的关键字扔到任何地方,就像它已经过时一样”是实现线程安全的一种非常糟糕的方式(例如,它实际上不会给你线程安全并减慢一切速度)。
推荐阅读
- xml - 获取重复元素名称的 XML 中属性的值
- python - pySpark - 在分组数据中查找共同值
- arrays - 将数据字符串从 numpy 数组转换为 int python
- keras - loading weights keras LSTM not working
- ruby-on-rails - nil:NilClass error with validation for numericality
- java - I am making a quiz app when i pressing the answer A,B,C,D it was not showing the next one
- linux-kernel - Linux内核wl18xx module_init是生成的吗?
- c# - How to move camera thats attached to player
- python - 如何在 Numpy 数组中设置单个索引
- c# - Deserialize JSON with empty string key