您可以安全地同步 Java 方法参数吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6209679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Can you safely synchronize on a Java method parameter?
提问by Android Dev
Take this code:
拿这个代码:
public class MyClass {
private final Object _lock = new Object();
private final MyMutableClass _mutableObject = new MyMutableClass()
public void myMethod() {
synchronized(_lock) { // we are synchronizing on instance variable _lock
// do something with mutableVar
//(i.e. call a "set" method on _mutableObject)
}
}
}
now, imagine delegating the code inside myMethod() to some helper class where you pass the lock
现在,想象一下将 myMethod() 中的代码委托给您传递锁的某个助手类
public class HelperClass {
public helperMethod(Object lockVar, MyMutableClass mutableVar) {
synchronized(lockVar) { // we are now synchronizing on a method param,
// each thread has own copy
// do something with mutableVar
// (i.e. call a "set" method on mutableVar)
}
}
}
can "myMethod" be re-written to use the HelperClass by passing its lock var, so that everything is still thread safe? i.e.,
是否可以通过传递其锁定变量来重写“myMethod”以使用 HelperClass,以便一切仍然是线程安全的?IE,
public void myMethod() {
_helperObject.helperMethod(_lock, _mutableObject);
}
I am not sure about this, because Java will pass the lockVar by value, and every thread will get a separate copy of lockVar (even though each copy points to the same object on the heap). I guess the question comes down to how 'synchronized' keyword works -- does it lock on the variable, or the value on the heap that the variable references?
我对此不确定,因为 Java 将按值传递 lockVar,并且每个线程都会获得 lockVar 的单独副本(即使每个副本都指向堆上的同一个对象)。我想问题归结为“同步”关键字的工作原理——它是锁定变量还是锁定变量引用的堆上的值?
采纳答案by Android Dev
Synchronization is done upon objects, not variables.
同步是在对象上完成的,而不是在变量上。
Variables/members [sometimes] contain objectsand it is the resulting objectcontained in [variable] x
that is actually synchronized upon in synchronized(x)
.
变量/成员 [有时] 包含对象,并且[variable]中包含的结果对象x
实际上在 in 上同步synchronized(x)
。
There are a few other issues with thread-visibility of variables (e.g. might read a "stale" object from a variable), but that does not apply here: there is no re-assignment of _lock
and the visibility of the initial ("final") assignment is guaranteed. Because of this it is guaranteed that, in this case, the method parameter will always contain the correct (same) objectused for the synchronization.
变量的线程可见性还存在一些其他问题(例如,可能会从变量中读取“陈旧”对象),但这不适用于此处:_lock
初始(“最终”)的可见性没有重新分配) 分配是有保证的。因此可以保证,在这种情况下,方法参数将始终包含用于同步的正确(相同)对象。
If the lock object used (where presumably _lock
is not final) changes, however, then that would require re-evaluation of the appropriate values/thread-visibility but otherwise does not differ from any cross-thread access.
但是,如果使用的锁定对象(可能_lock
不是最终的)发生变化,则需要重新评估适当的值/线程可见性,否则与任何跨线程访问没有区别。
Happy coding.
快乐编码。