我读到JVM通过根据此链接将共享变量的数据从主内存复制到线程的工作内存来实现同步。
例如,有一个这样的类。
class Test {
private Test2 test2 = new Test2();
public void print1() {}
public synchronized void print2() {
test2.print();
}
}
如果在多个线程中执行此Test类并且在一个线程中执行“print2”方法,我认为一个线程获取了对Test的锁定,而其他线程必须等到锁定被释放。
现在我有一个问题。如果线程获取了对Test的锁定,是否意味着Test和Test2的数据从主内存复制到线程的工作内存?我说的原因是“synchronized”关键字用于实例方法级别,test2是Test类的实例变量。
我只想澄清从主内存复制到线程工作内存的内容。
如果我错了,请纠正我。
答案 0 :(得分:2)
简而言之,当您使用synchronized时,将复制所有共享变量(即从高速缓存写入主内存,以便所有线程具有相同的数据)。使用volatile时,只保证复制一个volatile变量。
我发现这是一个有用的资源,涉及到这个主题。
http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
编辑:关于您的评论,specification的第17.6节回答了您的问题:
设T为任何线程,让V为任何变量,让L为任意锁。 对T执行的操作存在某些限制 尊重V和L:
在L上的T锁定动作和随后的使用或存储操作之间 通过T对变量V,V上的赋值或加载动作必须进行干预; 而且,如果是加载动作,则读取动作对应 该负载必须遵循锁定操作,如主存储器所示。 (不太正式:锁定操作就好像它会刷新所有变量一样 线程的工作记忆;在使用之前,他们必须被分配或 从主存储器加载。)
答案 1 :(得分:0)
synchronized。因为你没有修改任何东西,所以你不需要同步。
唯一复制的是引用test2
,它很可能被放在一个寄存器中。无论您的方法是否同步,都会发生这种情况。