【问题标题】:Volatile to be used with Concurrent Collection?与并发收集一起使用的易失性?
【发布时间】:2023-03-28 01:02:01
【问题描述】:

我正在开发一个metric store(Map),它主要收集一些操作的metrics,比如

  • 混合
  • 最大
  • 计数器
  • timeElapsed[] 等

这里的 Key 是方法的名称,value 是关于它的指标。

Spring 可以帮助我创建 MetricStore 的单例对象,我正在使用 ConcurrentHashMap 来避免 多个 REST 请求并行时出现竞争条件。

我的查询 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);
        }
    }

}

【问题讨论】:

  • re: "Map is not ThreadSafe"java.util.Map 不是线程安全或非线程安全的,它只是一些底层实现的接口。
  • 感谢@kaan 的评论

标签: java spring multithreading thread-safety concurrenthashmap


【解决方案1】:

我需要让 MetricStore 变量存储 volatile 吗?

不,因为您没有更改 store 的值(即 store 可以标记为 final 并且代码仍应编译)。

我使用 Map 作为基类,使用 ConcurrentHashMap 作为实现,它会影响 Map 不是 ThreadSafe

因为您使用ConcurrentHashMap 作为Map 的实现,所以它是线程安全的。如果您希望声明的类型更具体,可以将Map 更改为ConcurrentMap


这里更大的问题是你在调用putremove 之前使用containsKey,而你应该使用computecomputeIfPresent,它们是原子操作:

@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);
}

【讨论】:

  • 非常感谢您启发我。只是出于好奇和学习。计算是否像我使用同步块一样做同样的工作?
  • @DigitalAlchemist 比这要复杂一些。见:ConcurrentHashMap computeIfAbsent
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
相关资源
最近更新 更多