gpt4 book ai didi

java - 访问对象 Y 上定义的同步块(synchronized block)内的对象 X 是否安全?

转载 作者:行者123 更新时间:2023-12-01 16:57:05 25 4
gpt4 key购买 nike

在同步方法或同步块(synchronized block)中访问对象状态是否安全的问题已有答案。我的问题:访问同步块(synchronized block)中的对象 X 是否安全,其中同步块(synchronized block)位于另一个对象 Y 上,并且 X 存在多个写入线程?

public class X{
private int value = 0;
/** set method will be invoked by multiple threads**/
public void set(int v){
this.value = v;
}
public int value(){
return value;
}
}

public class Tester{
private final Object Y = new Object();
public void test(X x){
synchronized(Y){
System.out.println(x.value()); // is it guaranteed that x.value will be read from memory and not from the current thread's cache ?
}
}
}

我知道定义同步块(synchronized block)的对象的状态可以安全访问,不需要 volatile,但是如果同步块(synchronized block)是在另一个对象上定义的怎么办?

最佳答案

IMO,你问错了问题。 Java 内存模型本身不关心对象和类。它只讨论变量的可见性。

synchronized(o) block 的可见性规则非常简单:一个线程在离开 synchronized(o) block 之前对任何变量执行的任何操作都保证是在其他线程随后进入同一实例上同步的 block 之后,任何其他线程都可以看到,o

因此,在您的示例中,如果您有一些 X my_x,并且某个线程 A 会执行以下操作:

synchronized(Y) {
my_x.set(55);
}

然后,当其他线程 B 随后调用 tester.test(my_x) 时,线程 B 将看到线程 A 存储的值。

另一方面,如果线程 A 调用 my_x.set(...) 但没有Y 上进行同步,则 Java 不会 promise 线程 B 何时(如果有的话)会看到更改。

<小时/>

注意:您的程序通过将锁定对象 Y 设为 Tester 类的 private 成员,同时使test(X) 函数public。这实际上会要求您(或其他程序员)犯下调用 tester.test(some_random_X) 的错误,其中 some_random_X 是由另一个线程设置的,而该线程没有设置 锁定 Y

关于java - 访问对象 Y 上定义的同步块(synchronized block)内的对象 X 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61573152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com