要与并发收集一起使用吗?

问题描述 投票:1回答:1

我正在开发指标存储区(Map),基本上可以收集有关某些操作的指标,例如

  • mix
  • 最大
  • 计数器
  • timeElapsed []等

这里键是方法的名称,值是关于它的度量。

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

}
java spring multithreading thread-safety concurrenthashmap
1个回答
1
投票
我需要使MetricStore变量存储易失吗?

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

我使用Map作为基类,并使用ConcurrentHashMap作为Implemetnation,因为Map不是ThreadSafe会影响吗?>

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


这里更大的问题是,当您应该使用containsKeyput这是原子操作时,在调用removecompute之前先使用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); }

© www.soinside.com 2019 - 2024. All rights reserved.