使用 ConcurrentHashMap 的线程安全
Threadsafe with ConcurrentHashMap
我有一个问题,我需要在多线程环境中最多 运行 .register
一次,所以我尝试使用 ConcurrentHashMap 但似乎它不是线程安全的或我正在正确使用它
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()
)
}
}
抛出异常
Collector already registered that provides name: my_app_new_site_exclusion_worker_processing_time_count
于:
val onSuccessHistogram: Histogram.Child = NonFunctionalMetrics.workerProcessingHistogram(worker.name).labelSuccess()
val onFailureHistogram: Histogram.Child = NonFunctionalMetrics.workerProcessingHistogram(worker.name).labelFailure()
当我添加 synchronized
它的工作伟人时,如下所示:
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()
)
}
我看到 get(key)
两个线程正在获得 false
答案并使用 register
创建直方图 - ConcurrentHashMap 不需要处理这些场景吗?
您可以在基础 Java ConcurrentHashMap 上使用 computeIfAbsent
。但是 .asScala
返回的 ConcurrentMap 上的 getOrElseUpdate
将使用 Scala 中可变 Map 的 non-concurrent 实现。
我有一个问题,我需要在多线程环境中最多 运行 .register
一次,所以我尝试使用 ConcurrentHashMap 但似乎它不是线程安全的或我正在正确使用它
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()
)
}
}
抛出异常
Collector already registered that provides name: my_app_new_site_exclusion_worker_processing_time_count
于:
val onSuccessHistogram: Histogram.Child = NonFunctionalMetrics.workerProcessingHistogram(worker.name).labelSuccess()
val onFailureHistogram: Histogram.Child = NonFunctionalMetrics.workerProcessingHistogram(worker.name).labelFailure()
当我添加 synchronized
它的工作伟人时,如下所示:
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()
)
}
我看到 get(key)
两个线程正在获得 false
答案并使用 register
创建直方图 - ConcurrentHashMap 不需要处理这些场景吗?
您可以在基础 Java ConcurrentHashMap 上使用 computeIfAbsent
。但是 .asScala
返回的 ConcurrentMap 上的 getOrElseUpdate
将使用 Scala 中可变 Map 的 non-concurrent 实现。