Java易失性自定义对象-完整/深层对象可见性

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

我有以下内容:

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实现,但我想更好地了解如何在多线程环境中正确更新对象。

谢谢

java concurrency volatile
1个回答
0
投票

您的原始问题:我可以使用volatile获取地图的最新更新吗?

希望我能正确理解。

想象一下线程B是否执行MyCustomObject()构造函数这将使该MyCustomObject可用于其他线程。 (建议设置id是构造函数中的最后一条语句)

想象一下线程A是否执行addMyCustomObject线程A将获取最新的更新,包括正确构造的MyCustomObject实例。

为什么不建议使用这种编码?对于并发环境,上面的代码尚不清楚阅读和遵循。很脆弱。建议使用同步构造来阐明互斥和可见性。

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