Java 在不同对象可见性上同步

Java 在不同对象可见性上同步,java,multithreading,synchronized,volatile,Java,Multithreading,Synchronized,Volatile,以下代码显示与此不同的对象上的同步: public class A { int a,b,c,d; public void method1(Object x){ synchronized(x){ // is a ,b ,c ,d guarantee visibility ? } } public synchronized void method2() { a++; } } 我知道在method1和method2中使用不同的锁来编辑a、b

以下代码显示与此不同的对象上的同步:

public class A {

int a,b,c,d;

public void method1(Object x){
   synchronized(x){
     // is a ,b ,c ,d guarantee visibility ? 
   }
}

   public synchronized void method2() {
        a++;
    }
}

我知道在method1和method2中使用不同的锁来编辑a、b、c、d会有问题,但问题是method2刷新的更改对method1可见吗?因为它们不使用相同的锁。

如果您只读取
a
,在x64上,这将碰巧起作用,因为内存屏障不限于特定的内存位置。然而,我的理解是,Java不能保证这是线程安全的,因为锁应用于不同的对象。当然,如果您在第一个方法中增加
a
,它将不是线程安全的

我知道在method1和method2中使用不同的锁来编辑a、b、c、d会有问题,但问题是method2刷新的更改对method1可见吗?因为他们不用同一把锁


在没有任何其他同步的情况下,Java无法保证通过一个线程中的
a.method2()
a.a
执行的修改是否或何时对另一个线程中的
a.method1()
块内部或外部可见。出现该问题的程序未正确同步,因此其行为未定义。

从您的回答中,我理解这句话是正确的,对吗?线程内存刷新它的所有变量,即它的所有变量都有效地从“主”内存中读取。即使x将从主内存中读取?(我知道x是一个对象,应该在堆中,但这会迫使任何同步块从主存读取内部的每个变量吗?@MohammadKarmi出于性能原因,内核的二级缓存在它们之间传递最新的值,因此该值不必进入三级或主存。最后一个问题是了解所有内容。假设method2与method1在同一个x对象上同步,那么method1中的可见性是否保证为x、a、b、c、d?@MohammadKarmi是的。假设method2与同一个x对象同步(不是这个),那么可见性是否保证为x、a、b、c、d?如果
method2
包含同步块,然后,在执行该方法时,其中该块在某个对象
o1
上同步,该块内的代码将观察先前由同一块或在同一对象
o1
上同步的任何其他块执行的任何写入。同样,当该
o1
A.method1()
的参数时,该方法的同步块中的代码将观察该块或在同一
o1
上同步的任何其他块先前执行的任何写入,包括
method2()
@MohammadKarmi中的写入,此外,在同一对象上同步意味着一个同步块的执行总是在另一个块的执行之前或之后,尽管它没有说明哪个块先执行。这产生了进一步的影响,远远超出了两次处决不重叠的事实。