gpt4 book ai didi

java - 复合对象的同步方法如何工作

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

我很好奇下一个代码片段是否是线程安全的,特别是关注复合对象的synchronized关键字。如果updateAge发生在getB之前,第二个调用者会收到更新的年龄值吗?

如果答案是肯定的,请解释一下 JVM 如何执行该操作? (我假设JVM代码在退出同步方法/ block 时必须将访问的对象刷新到主内存,JVM代码是否从根对象中提取所有引用的对象?)

public class A {

private B b;

public B getB() { return b; }

public void setB(B b) { this.b = b; }
}

public class B {

private String name;
private Integer age;

public String getName() { return name; }

public void setName(String name) { this.name = name; }

public Integer getAge() { return age; }

public void setAge(Integer age) { this.age = age; }
}

public class Main {

private A a;

public Main() {
a = new A();
B b = new B();
b.setName("name");
b.setAge(10);
a.setB(b);
}

public synchronized void updateAge(Integer age){ a.getB().setAge(age); }

public synchronized B getB() { return a.getB(); }
}

更新1:

替代类是否等同于上面的原始主类?由于ConcurrentMap在put过程中执行同步。忽略 2 个并发线程调用 updateAge 方法的情况。

public class Main2 {

private ConcurrentMap<String, A> store = new ConcurrentHashMap<>();


public Main2() {
A a = new A();
B b = new B();
b.setName("name");
b.setAge(10);
a.setB(b);

store.put("id", a);
}

public void updateAge(Integer age){
A a = store.get("id");
a.getB().setAge(age);
store.put("id", a);
}

public B getB() { return store.get("id").getB(); }
}

最佳答案

这取决于您所说的线程安全的含义。如果系统仅包含这两个方法,那么答案是肯定的,这是线程安全的,因为updateAge()所做的任何更改都是线程安全的。 getB() 的调用者将可见.

但是自从getB()返回 B 的可变实例,没有什么可以阻止我写这样的东西:

Main main = ...;
main.updateAge(42); // we change the age of B in a synchronized block
B myLittleB = main.getB(); //this is synchronized to the same object, so it's all fine
myLittleB.setName("Boaty McBoatface"); //this isn't synchronized so if another thread calls main.getB().getName(), all bets are off

更新:如何实现可见性保证取决于 VM 实现和架构,但有几种可用的替代策略,例如运行时代码分析来确定哪些变量可能在同步块(synchronized block)中更改,或者甚至不加区别地冲掉所有东西。

关于java - 复合对象的同步方法如何工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37027855/

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