Bucketed metrics: Use separate object for double-checked locking
According to Findbugs: "This method performs synchronization an object that is an instance of a class from the java.util.concurrent package (or its subclasses). Instances of these classes have their own concurrency control mechanisms that are orthogonal to the synchronization provided by the Java keyword synchronized." Instead of synchronizing on the instance of ConcurrentHashMap, use a separate Object. Change-Id: Ie2c670c2a8617c453f5aa4005f51370c9772c77a
This commit is contained in:
@@ -38,6 +38,7 @@ abstract class BucketedCallback<V> implements BucketedMetric {
|
||||
private final V zero;
|
||||
private final Map<Object, ValueGauge> cells;
|
||||
protected volatile Runnable trigger;
|
||||
private final Object lock = new Object();
|
||||
|
||||
BucketedCallback(DropWizardMetricMaker metrics, MetricRegistry registry,
|
||||
String name, Class<V> valueType, Description desc, Field<?>... fields) {
|
||||
@@ -94,7 +95,7 @@ abstract class BucketedCallback<V> implements BucketedMetric {
|
||||
return c;
|
||||
}
|
||||
|
||||
synchronized (cells) {
|
||||
synchronized (lock) {
|
||||
c = cells.get(key);
|
||||
if (c == null) {
|
||||
c = new ValueGauge();
|
||||
|
||||
@@ -35,6 +35,7 @@ abstract class BucketedCounter implements BucketedMetric {
|
||||
protected final Field<?>[] fields;
|
||||
protected final CounterImpl total;
|
||||
private final Map<Object, CounterImpl> cells;
|
||||
private final Object lock = new Object();
|
||||
|
||||
BucketedCounter(DropWizardMetricMaker metrics,
|
||||
String name, Description desc, Field<?>... fields) {
|
||||
@@ -69,7 +70,7 @@ abstract class BucketedCounter implements BucketedMetric {
|
||||
return c;
|
||||
}
|
||||
|
||||
synchronized (cells) {
|
||||
synchronized (lock) {
|
||||
c = cells.get(key);
|
||||
if (c == null) {
|
||||
c = metrics.newCounterImpl(submetric(key), isRate);
|
||||
|
||||
@@ -34,6 +34,7 @@ abstract class BucketedHistogram implements BucketedMetric {
|
||||
protected final Field<?>[] fields;
|
||||
protected final HistogramImpl total;
|
||||
private final Map<Object, HistogramImpl> cells;
|
||||
private final Object lock = new Object();
|
||||
|
||||
BucketedHistogram(DropWizardMetricMaker metrics, String name,
|
||||
Description desc, Field<?>... fields) {
|
||||
@@ -67,7 +68,7 @@ abstract class BucketedHistogram implements BucketedMetric {
|
||||
return c;
|
||||
}
|
||||
|
||||
synchronized (cells) {
|
||||
synchronized (lock) {
|
||||
c = cells.get(key);
|
||||
if (c == null) {
|
||||
c = metrics.newHistogramImpl(submetric(key));
|
||||
|
||||
@@ -34,6 +34,7 @@ abstract class BucketedTimer implements BucketedMetric {
|
||||
protected final Field<?>[] fields;
|
||||
protected final TimerImpl total;
|
||||
private final Map<Object, TimerImpl> cells;
|
||||
private final Object lock = new Object();
|
||||
|
||||
BucketedTimer(DropWizardMetricMaker metrics, String name,
|
||||
Description desc, Field<?>... fields) {
|
||||
@@ -67,7 +68,7 @@ abstract class BucketedTimer implements BucketedMetric {
|
||||
return c;
|
||||
}
|
||||
|
||||
synchronized (cells) {
|
||||
synchronized (lock) {
|
||||
c = cells.get(key);
|
||||
if (c == null) {
|
||||
c = metrics.newTimerImpl(submetric(key));
|
||||
|
||||
Reference in New Issue
Block a user