22
22
import io .opentelemetry .sdk .resources .Resource ;
23
23
import java .util .Collection ;
24
24
import java .util .List ;
25
- import java .util .Objects ;
26
- import java .util .concurrent .atomic . AtomicReference ;
25
+ import java .util .concurrent . locks . Lock ;
26
+ import java .util .concurrent .locks . ReentrantLock ;
27
27
import java .util .function .Supplier ;
28
28
import javax .annotation .Nullable ;
29
29
import javax .annotation .concurrent .ThreadSafe ;
@@ -114,8 +114,7 @@ public MetricData toMetricData(
114
114
}
115
115
116
116
static final class Handle extends AggregatorHandle <DoublePointData , DoubleExemplarData > {
117
- @ Nullable private static final Double DEFAULT_VALUE = null ;
118
- private final AtomicReference <Double > current = new AtomicReference <>(DEFAULT_VALUE );
117
+ private final AtomicDouble current = new AtomicDouble ();
119
118
120
119
// Only used when memoryMode is REUSABLE_DATA
121
120
@ Nullable private final MutableDoublePointData reusablePoint ;
@@ -136,20 +135,50 @@ protected DoublePointData doAggregateThenMaybeReset(
136
135
Attributes attributes ,
137
136
List <DoubleExemplarData > exemplars ,
138
137
boolean reset ) {
139
- Double value = reset ? this .current .getAndSet (DEFAULT_VALUE ) : this .current .get ();
140
- if (reusablePoint != null ) {
141
- reusablePoint .set (
142
- startEpochNanos , epochNanos , attributes , Objects .requireNonNull (value ), exemplars );
143
- return reusablePoint ;
144
- } else {
138
+ double currentDouble = current .getAndReset ();
139
+ if (reusablePoint == null ) {
145
140
return ImmutableDoublePointData .create (
146
- startEpochNanos , epochNanos , attributes , Objects . requireNonNull ( value ) , exemplars );
141
+ startEpochNanos , epochNanos , attributes , currentDouble , exemplars );
147
142
}
143
+ reusablePoint .set (startEpochNanos , epochNanos , attributes , currentDouble , exemplars );
144
+ return reusablePoint ;
148
145
}
149
146
150
147
@ Override
151
148
protected void doRecordDouble (double value ) {
152
149
current .set (value );
153
150
}
154
151
}
152
+
153
+ private static final class AtomicDouble {
154
+ private final Lock lock = new ReentrantLock ();
155
+ private long current = 0 ;
156
+ private boolean set = false ;
157
+
158
+ public void set (double value ) {
159
+ long longValue = Double .doubleToLongBits (value );
160
+ lock .lock ();
161
+ try {
162
+ current = longValue ;
163
+ set = true ;
164
+ } finally {
165
+ lock .unlock ();
166
+ }
167
+ }
168
+
169
+ public double getAndReset () {
170
+ long currentLocal ;
171
+ lock .lock ();
172
+ try {
173
+ if (!set ) {
174
+ return 0 ;
175
+ }
176
+ currentLocal = current ;
177
+ set = false ;
178
+ } finally {
179
+ lock .unlock ();
180
+ }
181
+ return Double .longBitsToDouble (currentLocal );
182
+ }
183
+ }
155
184
}
0 commit comments