基于内存模型的java同步

基于内存模型的java同步,java,synchronization,Java,Synchronization,我读到JVM通过根据这个链接将共享变量的数据从主存复制到线程的工作内存来实现同步 例如,有这样一个类 class Test { private Test2 test2 = new Test2(); public void print1() {} public synchronized void print2() { test2.print(); } } 如果这个测试类在多个线程中执行,并且“print2”方法在一个线程中执行,那么我认为测试上的锁是由一个线程获得的,而其他线程必须

我读到JVM通过根据这个链接将共享变量的数据从主存复制到线程的工作内存来实现同步

例如,有这样一个类

class Test {
private Test2 test2 = new Test2();

public void print1() {}

public synchronized void print2() {
    test2.print();
}
}

如果这个测试类在多个线程中执行,并且“print2”方法在一个线程中执行,那么我认为测试上的锁是由一个线程获得的,而其他线程必须等待锁被释放

现在我有一个问题。如果线程获取了测试锁,是否意味着测试和测试2的数据从主内存复制到线程的工作内存?我说的原因是“synchronized”关键字用于实例方法级别,test2是测试类的实例变量

我只是想澄清什么是从主内存复制到线程的工作内存


如果我错了,请更正。

仅当您至少有一个a writer和a reader线程时才需要同步。由于您没有修改任何内容,因此不需要同步


唯一被复制的是引用
test2
,它很可能被放在寄存器中。无论您的方法是否同步,都会发生这种情况。

简而言之,当您使用同步时,所有共享变量都将被复制(即从缓存写入主内存,以便所有线程都具有相同的数据)。使用volatile时,只能保证复制一个volatile变量

我发现这是一个有用的资源,涉及到这个主题




编辑:关于您的评论,第17.6节回答您的问题:

设T为任意线程,V为任意变量,L为任意锁。 对T执行的操作有一定的限制 关于V和L:

在T对L的锁定操作和随后的使用或存储操作之间 通过变量V上的T,V上的赋值或加载动作必须介入; 此外,如果它是一个加载动作,则读取动作对应 如主内存所示,加载必须遵循锁定操作。 (不太正式:锁操作的行为就像它从 线程的工作内存;在使用之前,必须对其进行分配或 从主存加载。


我知道这个类没有修改任何东西。这只是一个例子。我只是想找出在JVM中进行同步时复制的是什么。因此,如果有另一个实例变量,比如String s=“test”,那么这个“s”也会被复制?实际上,在这个示例中有一个writer<代码>私有Test2 Test2=newtest2()执行写入操作。@Yair,这是在将是单线程的构造函数中执行的。@user826323,
s
将被复制,如果您使用它。同样,使用synchronized对于普通读取没有任何区别。如果我使用类似这样的synchronized块,而不是在方法级别使用“synchronized”,会发生什么?对象锁=新对象();synchronized(lock){test2.print();}@user826323我必须刷新内存才能回答这个问题。请参阅我的最新答案。当使用锁时,所有共享变量将从主存中获取。