简体   繁体   中英

Threadsafe with ConcurrentHashMap

I have an issue on which I need to run .register at most one time on a multi-threaded env, so i tried to use ConcurrentHashMap but seems like its not thread-safe or I'm using it correctly

object NonFunctionalMetrics {

  val histograms = new ConcurrentHashMap[String, Histogram](10).asScala
  def workerProcessingHistogram(name: String): Histogram = {
    val histogramName = s"${prefix}_${name.toSnakeCase}_processing_time"
    histograms.getOrElseUpdate(
                              key = histogramName,
                              op = Histogram.build(histogramName, s"${name} worker processing time in microseconds")
                                .labelNames("status")
                                .linearBuckets(config.service.metrics.http.histogramStart, config.service.metrics.http.histogramWidth, config.service.metrics.http.histogramCount)
                                .register()
    )
  }
}

throws me exception

Collector already registered that provides name: my_app_new_site_exclusion_worker_processing_time_count

on:

    val onSuccessHistogram: Histogram.Child = NonFunctionalMetrics.workerProcessingHistogram(worker.name).labelSuccess()
    val onFailureHistogram: Histogram.Child = NonFunctionalMetrics.workerProcessingHistogram(worker.name).labelFailure()

When I'm adding synchronized its working greats, as follows:

 def workerProcessingHistogram(name: String): Histogram = synchronized {
    val histogramName = s"${prefix}_${name.toSnakeCase}_processing_time"
    histograms.getOrElseUpdate(
                              key = histogramName,
                              op = Histogram.build(histogramName, s"${name} worker processing time in microseconds")
                                .labelNames("status")
                                .linearBuckets(config.service.metrics.http.histogramStart, config.service.metrics.http.histogramWidth, config.service.metrics.http.histogramCount)
                                .register()
    )
  }

I saw that the get(key) two threads are getting false answer and create the histogram with register - doesn't the ConcurrentHashMap need to handle those scenarios?

You could use computeIfAbsent on the underlying Java ConcurrentHashMap. But getOrElseUpdate on a ConcurrentMap returned by .asScala will use the non-concurrent implementation of mutable Map in Scala.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM