同步的 getter 方法是否看到完全或部分初始化的对象?

问题描述 投票:0回答:1

假设我有下一堂课:

class Point {

    int x, y, z;

    public Point(int x, int y, int z) {
        this.x = x; 
        this.y = y; 
        this.z = z;  
    }

    public **synchronized** int getSum() {
        return x + y + z;
    }
}

因此,如果我要共享对许多线程的引用,是否可以在 syncronized getSum() 方法中拥有部分初始化的字段?

Point p = new Point(1,2,3);
int sum = p.getSum();

是否有可能得到如下结果:

sum = 0 (OK);
sum = 6 (OK);
sum = 1 (x = 1, y = 0, z = 0) (INTERESTING);
sum = 2 (x = 0, y = 2, z = 0) (INTERESTING);
sum = 3 (x = 0, y = 0, z = 3) (INTERESTING);
sum = 5 (x = 1, y = 2, z = 3) (INTERESTING);
and so on..

这里真的有happens-before保证吗?如果一个线程获得了Point的锁并进入了synchronized方法,是否意味着调用构造函数的线程已经完成了所有的初始化?

谢谢。

对我来说很明显,有可能得到下一个结果:

sum = 0 (OK);
sum = 6 (OK);

下一个不变量呢?可以有吗

sum = 1 (x = 1, y = 0, z = 0) (INTERESTING);
sum = 2 (x = 0, y = 2, z = 0) (INTERESTING);
sum = 3 (x = 0, y = 0, z = 3) (INTERESTING);
sum = 5 (x = 1, y = 2, z = 3) (INTERESTING);
java memory concurrency synchronization visibility
1个回答
0
投票

Synchronized 提供原子性和可见性,因此总和应始终保持一致。

© www.soinside.com 2019 - 2024. All rights reserved.