你能安全地同步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 //(ie 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 // (ie call a "set" method on mutableVar) } } }
是否可以通过传递其锁定var来重写“myMethod”以使用HelperClass,以便一切仍然是线程安全的? 即
public void myMethod() { _helperObject.helperMethod(_lock, _mutableObject); }
我不确定这一点,因为Java将通过值传递lockVar,并且每个线程将获得一个单独的lockVar副本(即使每个副本指向堆上的同一个对象)。 我想这个问题归结为’synchronized’关键字是如何工作的 – 它是锁定变量还是变量引用的堆上的值?
同步是在对象而不是变量上完成的 。
变量/成员[有时]包含对象 ,它是[variable] x
中包含的结果对象 ,实际上在synchronized(x)
中synchronized(x)
。
变量的线程可见性还存在一些其他问题(例如,可能从变量中读取“陈旧”对象),但这不适用于:没有_lock
重新赋值和初始的可见性(“final” “)保证分配。 因此,可以保证在这种情况下,方法参数将始终包含用于同步的正确(相同) 对象 。
但是,如果使用的锁定对象(可能是_lock
不是最终的)发生了变化,则需要重新评估适当的值/线程可见性,但不会与任何跨线程访问不同。
快乐的编码。
- 处理2d数组或文件中的行范围
- 为什么有些人在通信中使用Class#方法而不是Class.method?
- 配置为目标的PN532已由其启动器释放
- 为什么调用方法的Java字节码隐式获取和释放监视器?
- 什么是’cpumin.exe’进程在后台运行并占用100%的CPU? 每当我运行Java程序时都会发生这种情况
- JCE无法在java swing应用程序中validation提供程序BC
- 我的JFrame类中的线程“AWT-EventQueue-0”java.lang.ClassCastException中的exception
- 处理HTTP ContentEncoding“deflate”
- Java 8 Stream API中的多个聚合函数