你能安全地同步Java方法参数吗? [英] Can you safely synchronize on a Java method parameter?

查看:590
本文介绍了你能安全地同步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()中的代码委托给你传递锁的一些助手类

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

可以通过传递myMethod来重写它以使用HelperClass s lock var,这样一切仍然是线程安全的吗?即,

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

我不确定这一点,因为Java会按值传递lockVar,并且每个线程都将获得一个单独的lockVar副本(即使每个副本指向堆上的同一个对象)。我想这个问题归结为'synchronized'关键字如何工作 - 它是否锁定变量,或变量引用的堆上的值?

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.

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

Variables/members [sometimes] contain objects and it is the resulting object contained in [variable] x that is actually synchronized upon in synchronized(x).

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

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.

但是,如果使用的锁定对象(可能 _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.

快乐编码。

这篇关于你能安全地同步Java方法参数吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆