我有以下内容:
public class MainClass {
private final Map<Integer, List<MyCustomObject>> myMap = new HashMap<>();
public addMyCustomObject(MyCustomObject customObj) {
List<MyCustomObject> customObjList = myMap.get(customObj.getId());
if (customObjList == null) {
customObjList = new LinkedList<>();
}
customObjList.add(customObj);
}
public List<MyCustomObject> getList(int customObjId) {
return myMap.get(customObjId);
}
}
public class MyCustomObject {
private volatile MyCustomObject sonCustomObject;
private volatile int id;
public MyCustomObject(MyCustomObject sonCustomObject, int id) {
this.id = id;
this.sonCustomObject = sonCustomObject;
}
public void changeId(int newId) {
this.id = newId;
}
public int getId() {
return this.id;
}
public void changeSon(MyCustomObject sonCustomObject) {
this.sonCustomObject.setId(-1);
this.sonCustomObject = sonCustomObject;
this.sonCustomObject.setId(this.id);
}
}
我知道仅使列表易变是不够的,因为我不仅需要引用,还需要更新内部对象的状态。使MyCustomObject的内部字段可变是否可以解决我的问题?
对于此示例,我并不关心“独占访问”,在这种情况下,我将使用同步或ReentrantLocks。我只需要确保使用相同的MainClass实例为所有线程始终更新所有内容。
我可以使用ConcurrentHashMap实现,但我想更好地了解如何在多线程环境中正确更新对象。
谢谢
您的原始问题:我可以使用volatile获取地图的最新更新吗?
希望我能正确理解。
想象一下线程B是否执行MyCustomObject()构造函数这将使该MyCustomObject可用于其他线程。 (建议设置id是构造函数中的最后一条语句)
想象一下线程A是否执行addMyCustomObject线程A将获取最新的更新,包括正确构造的MyCustomObject实例。
为什么不建议使用这种编码?对于并发环境,上面的代码尚不清楚阅读和遵循。很脆弱。建议使用同步构造来阐明互斥和可见性。