我有一个ConcurrentHashMap:
TOwnProps
在我的应用程序中,此映射为高读和低写
阅读方式如下:
ownProps
更新通过以下方式工作:
ConcurrentHashMap<ID,Object> map;
现在我的问题是,ConcurrentHashMap是否足以让上述情况在多线程环境中以线程安全的方式工作,还是我必须通过ReadWrite锁从外部锁定Object或使用Object的克隆?
假设在从地图读取obj的情况下,ConcurrentHashMap将确保它将返回最新的写入对象,但是当在读取后立即由编写器线程删除/更新该对象时该怎么办。Read对象(已经删除/更新了)来自地图)用于准备响应对象,其属性用于做出某些决策。
什么是更新地图的更好方法?
答案 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
作为自定义类,而应使用新名称。
在读取后立即由编写器线程删除/更新该对象的时间
如果删除该对象,则对持有该引用的另一个线程没有影响。如果通过在地图中放置新对象来更新对象,则可以,但是,如果更新添加的对象,则可能不是线程安全的。