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
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.,
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?
Synchronization is done upon objects, not variables.
Variables/members [sometimes] contain objects and it is the resulting object contained in [variable] x
that is actually synchronized upon 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) object used for the synchronization.
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.
Happy coding.