我正在开发指标存储区(Map),基本上可以收集有关某些操作的指标,例如
这里键是方法的名称,值是关于它的度量。
Spring可以帮助我创建MetricStore的单例对象,我正在使用ConcurrentHashMap来避免多个REST请求并行出现时的竞争状态。
我的查询1-我需要使MetricStore变量存储易变吗?以提高多个请求之间的可见性。 2-我使用Map作为基类,并使用ConcurrentHashMap作为Implemetnation,因为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作为Implemetnation,因为Map不是ThreadSafe会影响吗?>因为您使用
ConcurrentHashMap
作为Map
的实现,所以它是线程安全的。如果要声明的类型更具体,可以将Map
更改为ConcurrentMap
。
containsKey
和put
这是原子操作时,在调用remove
和compute
之前先使用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);
}