开发者

Can you safely synchronize on a Java method parameter?

Take this code:

public class MyClass {
    p开发者_如何学编程rivate 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜