对ConcurrentHashMap的值对象同时读写

时间:2018-11-03 15:40:29

标签: java multithreading concurrenthashmap

我有一个ConcurrentHashMap:

TOwnProps

在我的应用程序中,此映射为高读和低写

阅读方式如下:

ownProps

更新通过以下方式工作:

ConcurrentHashMap<ID,Object> map;

现在我的问题是,ConcurrentHashMap是否足以让上述情况在多线程环境中以线程安全的方式工作,还是我必须通过ReadWrite锁从外部锁定Object或使用Object的克隆?

假设在从地图读取obj的情况下,ConcurrentHashMap将确保它将返回最新的写入对象,但是当在读取后立即由编写器线程删除/更新该对象时该怎么办。Read对象(已经删除/更新了)来自地图)用于准备响应对象,其属性用于做出某些决策。

什么是更新地图的更好方法?

2 个答案:

答案 0 :(得分:0)

要使代码相对于compute是线程安全的,应使用相应的public Response getObject() { Response response = createResponse(); map.computeIfPresent(ID, (k, v) -> { if (v == some_value) { response.setAttr1(v.getAttr1()); response.setAttr2(v.getAttr2()); } return v; } return response; } 方法(原子执行):

public void updateObject(Object obj, int action) {
    if (action == ADD) {
        map.put(obj.getID(), obj);
    } else if (action == UPDATE) {
        map.computeIfPresent(obj.getID(), (k, v) -> obj);
    } else if (action == REMOVE) {
        map.remove(obj.getID());
    }
}

并且:

| async

答案 1 :(得分:-1)

这是线程安全的,前提是只有一个编写器。否则,您执行的操作之间会出现竞争状态。因此,有些操作可以自动执行这些操作并简化代码。

public void updateObject(Object obj, int action) {
    switch (action) {
        case ADD:
            map.put(obj.getID(), obj);
            break;

        case UPDATE:
            map.computeIfPresent(obj.getID(), (k, v) -> obj);
            break;

        case REMOVE:
            map.remove(obj.getID());
            break;
    }
}

很可能,您不需要特殊的更新操作,也可以put

我强烈建议不要使用Object作为自定义类,而应使用新名称。

  

在读取后立即由编写器线程删除/更新该对象的时间

如果删除该对象,则对持有该引用的另一个线程没有影响。如果通过在地图中放置新对象来更新对象,则可以,但是,如果更新添加的对象,则可能不是线程安全的。