ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/concurrent/atomic/DoubleAdder.java
Revision: 1.1
Committed: Sat Mar 26 06:22:51 2016 UTC (8 years, 2 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Log Message:
fork jdk8 maintenance branch for source and jtreg tests

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 package java.util.concurrent.atomic;
8
9 import java.io.Serializable;
10
11 /**
12 * One or more variables that together maintain an initially zero
13 * {@code double} sum. When updates (method {@link #add}) are
14 * contended across threads, the set of variables may grow dynamically
15 * to reduce contention. Method {@link #sum} (or, equivalently {@link
16 * #doubleValue}) returns the current total combined across the
17 * variables maintaining the sum. The order of accumulation within or
18 * across threads is not guaranteed. Thus, this class may not be
19 * applicable if numerical stability is required, especially when
20 * combining values of substantially different orders of magnitude.
21 *
22 * <p>This class is usually preferable to alternatives when multiple
23 * threads update a common value that is used for purposes such as
24 * summary statistics that are frequently updated but less frequently
25 * read.
26 *
27 * <p>This class extends {@link Number}, but does <em>not</em> define
28 * methods such as {@code equals}, {@code hashCode} and {@code
29 * compareTo} because instances are expected to be mutated, and so are
30 * not useful as collection keys.
31 *
32 * @since 1.8
33 * @author Doug Lea
34 */
35 public class DoubleAdder extends Striped64 implements Serializable {
36 private static final long serialVersionUID = 7249069246863182397L;
37
38 /*
39 * Note that we must use "long" for underlying representations,
40 * because there is no compareAndSet for double, due to the fact
41 * that the bitwise equals used in any CAS implementation is not
42 * the same as double-precision equals. However, we use CAS only
43 * to detect and alleviate contention, for which bitwise equals
44 * works best anyway. In principle, the long/double conversions
45 * used here should be essentially free on most platforms since
46 * they just re-interpret bits.
47 */
48
49 /**
50 * Creates a new adder with initial sum of zero.
51 */
52 public DoubleAdder() {
53 }
54
55 /**
56 * Adds the given value.
57 *
58 * @param x the value to add
59 */
60 public void add(double x) {
61 Cell[] as; long b, v; int m; Cell a;
62 if ((as = cells) != null ||
63 !casBase(b = base,
64 Double.doubleToRawLongBits
65 (Double.longBitsToDouble(b) + x))) {
66 boolean uncontended = true;
67 if (as == null || (m = as.length - 1) < 0 ||
68 (a = as[getProbe() & m]) == null ||
69 !(uncontended = a.cas(v = a.value,
70 Double.doubleToRawLongBits
71 (Double.longBitsToDouble(v) + x))))
72 doubleAccumulate(x, null, uncontended);
73 }
74 }
75
76 /**
77 * Returns the current sum. The returned value is <em>NOT</em> an
78 * atomic snapshot; invocation in the absence of concurrent
79 * updates returns an accurate result, but concurrent updates that
80 * occur while the sum is being calculated might not be
81 * incorporated. Also, because floating-point arithmetic is not
82 * strictly associative, the returned result need not be identical
83 * to the value that would be obtained in a sequential series of
84 * updates to a single variable.
85 *
86 * @return the sum
87 */
88 public double sum() {
89 Cell[] as = cells;
90 double sum = Double.longBitsToDouble(base);
91 if (as != null) {
92 for (Cell a : as)
93 if (a != null)
94 sum += Double.longBitsToDouble(a.value);
95 }
96 return sum;
97 }
98
99 /**
100 * Resets variables maintaining the sum to zero. This method may
101 * be a useful alternative to creating a new adder, but is only
102 * effective if there are no concurrent updates. Because this
103 * method is intrinsically racy, it should only be used when it is
104 * known that no threads are concurrently updating.
105 */
106 public void reset() {
107 Cell[] as = cells;
108 base = 0L; // relies on fact that double 0 must have same rep as long
109 if (as != null) {
110 for (Cell a : as)
111 if (a != null)
112 a.reset();
113 }
114 }
115
116 /**
117 * Equivalent in effect to {@link #sum} followed by {@link
118 * #reset}. This method may apply for example during quiescent
119 * points between multithreaded computations. If there are
120 * updates concurrent with this method, the returned value is
121 * <em>not</em> guaranteed to be the final value occurring before
122 * the reset.
123 *
124 * @return the sum
125 */
126 public double sumThenReset() {
127 Cell[] as = cells;
128 double sum = Double.longBitsToDouble(base);
129 base = 0L;
130 if (as != null) {
131 for (Cell a : as) {
132 if (a != null) {
133 long v = a.value;
134 a.reset();
135 sum += Double.longBitsToDouble(v);
136 }
137 }
138 }
139 return sum;
140 }
141
142 /**
143 * Returns the String representation of the {@link #sum}.
144 * @return the String representation of the {@link #sum}
145 */
146 public String toString() {
147 return Double.toString(sum());
148 }
149
150 /**
151 * Equivalent to {@link #sum}.
152 *
153 * @return the sum
154 */
155 public double doubleValue() {
156 return sum();
157 }
158
159 /**
160 * Returns the {@link #sum} as a {@code long} after a
161 * narrowing primitive conversion.
162 */
163 public long longValue() {
164 return (long)sum();
165 }
166
167 /**
168 * Returns the {@link #sum} as an {@code int} after a
169 * narrowing primitive conversion.
170 */
171 public int intValue() {
172 return (int)sum();
173 }
174
175 /**
176 * Returns the {@link #sum} as a {@code float}
177 * after a narrowing primitive conversion.
178 */
179 public float floatValue() {
180 return (float)sum();
181 }
182
183 /**
184 * Serialization proxy, used to avoid reference to the non-public
185 * Striped64 superclass in serialized forms.
186 * @serial include
187 */
188 private static class SerializationProxy implements Serializable {
189 private static final long serialVersionUID = 7249069246863182397L;
190
191 /**
192 * The current value returned by sum().
193 * @serial
194 */
195 private final double value;
196
197 SerializationProxy(DoubleAdder a) {
198 value = a.sum();
199 }
200
201 /**
202 * Returns a {@code DoubleAdder} object with initial state
203 * held by this proxy.
204 *
205 * @return a {@code DoubleAdder} object with initial state
206 * held by this proxy
207 */
208 private Object readResolve() {
209 DoubleAdder a = new DoubleAdder();
210 a.base = Double.doubleToRawLongBits(value);
211 return a;
212 }
213 }
214
215 /**
216 * Returns a
217 * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.DoubleAdder.SerializationProxy">
218 * SerializationProxy</a>
219 * representing the state of this instance.
220 *
221 * @return a {@link SerializationProxy}
222 * representing the state of this instance
223 */
224 private Object writeReplace() {
225 return new SerializationProxy(this);
226 }
227
228 /**
229 * @param s the stream
230 * @throws java.io.InvalidObjectException always
231 */
232 private void readObject(java.io.ObjectInputStream s)
233 throws java.io.InvalidObjectException {
234 throw new java.io.InvalidObjectException("Proxy required");
235 }
236
237 }