java - 您可以安全地同步 Java 方法参数吗?

标签 java methods parameters locking synchronized

拿这段代码:

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() 中的代码委托(delegate)给传递锁的某个辅助类

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”关键字是如何工作的——它是锁定变量,还是锁定变量引用的堆上的值?

最佳答案

同步是在对象上完成的,而不是变量

变量/成员 [有时] 包含 对象 并且它是包含在 [变量] x 中的结果 对象 实际上是同步的同步(x)

变量的线程可见性还有一些其他问题(例如,可能从变量中读取“陈旧”对象),但这不适用于此处:_lock 没有重新分配> 并保证初始(“最终”)分配的可见性。因此可以保证,在这种情况下,方法参数将始终包含用于同步的正确(相同)对象

但是,如果使用的锁对象(假定 _lock 不是最终的)发生变化,那么这将需要重新评估适当的值/线程可见性,但在其他方面与任何交叉没有区别-线程访问。

快乐编码。

关于java - 您可以安全地同步 Java 方法参数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6209679/

相关文章:

java - 正则表达式匹配至少包含 n 个数字的非字母字符序列

C++:在方法内部可以从类创建未初始化的对象吗?

symfony - 如何在 Twig 文件中获取参数

python - 如何自动设置 pytest.param id?

javascript - 为了让函数一 "know"对函数二中发生的事情使用react,参数是如何参与的?

java - 存储运行时之间的映射

Java android java.util.ConcurrentModificationException

java - 当另一个面板动态移动时如何自动正确调整面板大小 java swing

Java:返回 String 或 int 的方法

git - 如何列出提交中更改的所有方法的签名?