Можно ли безопасно выполнить синхронизацию с параметром метода Java?

Возьмите этот код:

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)
        }
    }
}

Теперь представьте делегирование кода внутри 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)
        }
    }
}

можно ли переписать myMethod для использования HelperClass, передав его переменную блокировки, чтобы все по-прежнему было потокобезопасным? т.е.

public void myMethod() {
    _helperObject.helperMethod(_lock, _mutableObject);
}

Я не уверен в этом, потому что Java передаст lockVar по значению, и каждый поток получит отдельную копию lockVar (даже если каждая копия указывает на один и тот же объект в куче). Думаю, вопрос сводится к тому, как работает ключевое слово «synchronized» - блокирует ли оно переменную или значение в куче, на которое ссылается переменная?

18
задан javac 14 April 2015 в 18:13
поделиться