Volatile 与并发收集一起使用?
Volatile to be used with Concurrent Collection?
我正在开发一个指标存储 (Map),它基本上收集有关某些操作的指标,例如
- 混合
- 最大值
- 计数器
- 已用时间[] 等
这里的 Key 是方法的名称,value 是关于它的指标。
Spring 可以帮助我创建 MetricStore 的单例对象,我正在使用 ConcurrentHashMap 来避免竞争条件 多个 REST 请求并行。
我的查询
1- 我是否需要使 MetricStore 变量存储可变?提高多个请求之间的可见性。 2- 我使用 Map 作为基础 class 和 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);
}
}
}
Do i need to make MetricStore variable store volatile?
不,因为您没有更改 store
的值(即 store
可以标记为 final
并且代码仍应编译)。
I am using Map as the base class and ConcurrentHashMap as Implemetnation, does it affect as Map is not ThreadSafe
因为您使用 ConcurrentHashMap
作为 Map
的实现,它是线程安全的。如果希望声明的类型更具体,可以将Map
改为ConcurrentMap
.
这里更大的问题是你在调用 put
和 remove
之前使用 containsKey
而你应该使用 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);
}
我正在开发一个指标存储 (Map),它基本上收集有关某些操作的指标,例如
- 混合
- 最大值
- 计数器
- 已用时间[] 等
这里的 Key 是方法的名称,value 是关于它的指标。
Spring 可以帮助我创建 MetricStore 的单例对象,我正在使用 ConcurrentHashMap 来避免竞争条件 多个 REST 请求并行。
我的查询 1- 我是否需要使 MetricStore 变量存储可变?提高多个请求之间的可见性。 2- 我使用 Map 作为基础 class 和 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);
}
}
}
Do i need to make MetricStore variable store volatile?
不,因为您没有更改 store
的值(即 store
可以标记为 final
并且代码仍应编译)。
I am using Map as the base class and ConcurrentHashMap as Implemetnation, does it affect as Map is not ThreadSafe
因为您使用 ConcurrentHashMap
作为 Map
的实现,它是线程安全的。如果希望声明的类型更具体,可以将Map
改为ConcurrentMap
.
这里更大的问题是你在调用 put
和 remove
之前使用 containsKey
而你应该使用 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);
}