java - 与并发收集一起使用的易失性?
问题描述
我正在开发一个指标存储(Map),它基本上收集有关某些操作的指标,例如
- 混合
- 最大限度
- 柜台
- timeElapsed[] 等
这里 Key 是方法的名称, value 是关于它的指标。
Spring 可以帮助我创建MetricStore的单例对象,当多个 REST 请求并行出现时,我正在使用ConcurrentHashMap来避免竞争条件。
我的查询 1- 我需要使 MetricStore 变量存储易失吗?提高多个请求之间的可见性。2-我使用 Map 作为基类,使用 ConcurrentHashMap 作为实现,它是否会影响 Map 不是 ThreadSafe。-
@Component
class MetricStore{
public Map<String, Metric> store = new ConcurrentHashMap<>();
//OR public volatile Map<String, Metric> store = new ConcurrentHashMap<>();
}
@RestController
class MetricController{
@Autowired
private MetricStore metricStore;
@PostMapping(name="put")
public void putData(String key, Metric metricData) {
if(metricStore.store.containsKey(key)) {
// udpate data
}
else {
metricStore.store.put(key, metricData);
}
}
@PostMapping(name="remove")
public void removeData(String key) {
if(metricStore.store.containsKey(key)) {
metricStore.store.remove(key);
}
}
}
解决方案
我需要使 MetricStore 变量存储易失吗?
不,因为您没有更改 的值store
(即store
可以标记为final
并且代码仍应编译)。
我使用 Map 作为基类,使用 ConcurrentHashMap 作为实现,它是否会影响 Map 不是 ThreadSafe
因为您使用 aConcurrentHashMap
作为 的实现Map
,所以它是线程安全的。如果您希望声明的类型更具体,Map
可以更改为ConcurrentMap
.
这里更大的问题是您containsKey
在调用之前使用put
以及remove
何时应该使用compute
and computeIfPresent
,这是原子操作:
@PostMapping(name="put")
public void putData(String key, Metric metricData) {
metricStore.store.compute(key, (k, v) -> {
if (v == null) {
return metricData;
}
// update data
});
}
@PostMapping(name="remove")
public void removeData(String key) {
metricStore.store.computeIfPresent(key, (k, v) -> null);
}
推荐阅读
- azure-data-factory - Azure 数据资源管理器命令动态参数错误
- json - 用权重值标记弧形图弧
- vue.js - 没有版本代码的 Vue CLI 服务生产构建?
- angular - 检索 Angular FormGroup 中每个字段的值
- java - 在springboot中发送响应时,我们是否有任何注释来验证响应属性/字段不为空?
- html - CSS/HTML 环绕图像的文本不起作用
- react-native - React Native 中的树形图形状并不完美(d3,react-native-svg)
- python - 在 cloudwatch 中提取 API 请求日志
- javascript - 如何删除“chrome正在由自动化测试软件控制”selenium javascript
- python - 将 [spacy list of pos_] 转换为 [list of tag_ ]