ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/DoubleAdder.java
Revision: 1.5
Committed: Sun Nov 18 03:07:22 2012 UTC (11 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.4: +1 -1 lines
Log Message:
properly close <em> javadoc tags

File Contents

# User Rev Content
1 dl 1.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 jsr166e;
8     import java.io.IOException;
9     import java.io.Serializable;
10     import java.io.ObjectInputStream;
11     import java.io.ObjectOutputStream;
12    
13     /**
14     * One or more variables that together maintain an initially zero
15     * {@code double} sum. When updates (method {@link #add}) are
16     * contended across threads, the set of variables may grow dynamically
17     * to reduce contention. Method {@link #sum} (or, equivalently {@link
18     * #doubleValue}) returns the current total combined across the
19     * variables maintaining the sum.
20     *
21     * <p>This class extends {@link Number}, but does <em>not</em> define
22     * methods such as {@code hashCode} and {@code compareTo} because
23     * instances are expected to be mutated, and so are not useful as
24     * collection keys.
25     *
26     * <p><em>jsr166e note: This class is targeted to be placed in
27 jsr166 1.5 * java.util.concurrent.atomic.</em>
28 dl 1.1 *
29 jsr166 1.2 * @since 1.8
30 dl 1.1 * @author Doug Lea
31     */
32     public class DoubleAdder extends Striped64 implements Serializable {
33     private static final long serialVersionUID = 7249069246863182397L;
34    
35     /**
36     * Update function. Note that we must use "long" for underlying
37     * representations, because there is no compareAndSet for double,
38     * due to the fact that the bitwise equals used in any CAS
39     * implementation is not the same as double-precision equals.
40     * However, we use CAS only to detect and alleviate contention,
41     * for which bitwise equals works best anyway. In principle, the
42     * long/double conversions used here should be essentially free on
43     * most platforms since they just re-interpret bits.
44     *
45     * Similar conversions are used in other methods.
46     */
47     final long fn(long v, long x) {
48     return Double.doubleToRawLongBits
49     (Double.longBitsToDouble(v) +
50     Double.longBitsToDouble(x));
51     }
52    
53     /**
54     * Creates a new adder with initial sum of zero.
55     */
56     public DoubleAdder() {
57     }
58    
59     /**
60     * Adds the given value.
61     *
62     * @param x the value to add
63     */
64     public void add(double x) {
65     Cell[] as; long b, v; HashCode hc; Cell a; int n;
66     if ((as = cells) != null ||
67     !casBase(b = base,
68     Double.doubleToRawLongBits
69     (Double.longBitsToDouble(b) + x))) {
70     boolean uncontended = true;
71     int h = (hc = threadHashCode.get()).code;
72     if (as == null || (n = as.length) < 1 ||
73     (a = as[(n - 1) & h]) == null ||
74     !(uncontended = a.cas(v = a.value,
75     Double.doubleToRawLongBits
76     (Double.longBitsToDouble(v) + x))))
77     retryUpdate(Double.doubleToRawLongBits(x), hc, uncontended);
78     }
79     }
80    
81     /**
82     * Returns the current sum. The returned value is <em>NOT</em> an
83     * atomic snapshot: Invocation in the absence of concurrent
84     * updates returns an accurate result, but concurrent updates that
85     * occur while the sum is being calculated might not be
86     * incorporated. Also, because double-precision arithmetic is not
87     * strictly associative, the returned result need not be identical
88     * to the value that would be obtained in a sequential series of
89     * updates to a single variable.
90     *
91     * @return the sum
92     */
93     public double sum() {
94     Cell[] as = cells;
95     double sum = Double.longBitsToDouble(base);
96     if (as != null) {
97     int n = as.length;
98     for (int i = 0; i < n; ++i) {
99     Cell a = as[i];
100     if (a != null)
101     sum += Double.longBitsToDouble(a.value);
102     }
103     }
104     return sum;
105     }
106    
107     /**
108     * Resets variables maintaining the sum to zero. This method may
109     * be a useful alternative to creating a new adder, but is only
110     * effective if there are no concurrent updates. Because this
111     * method is intrinsically racy, it should only be used when it is
112     * known that no threads are concurrently updating.
113     */
114     public void reset() {
115     internalReset(0L);
116     }
117    
118     /**
119     * Equivalent in effect to {@link #sum} followed by {@link
120     * #reset}. This method may apply for example during quiescent
121     * points between multithreaded computations. If there are
122     * updates concurrent with this method, the returned value is
123     * <em>not</em> guaranteed to be the final value occurring before
124     * the reset.
125     *
126     * @return the sum
127     */
128     public double sumThenReset() {
129     Cell[] as = cells;
130     double sum = Double.longBitsToDouble(base);
131     base = 0L;
132     if (as != null) {
133     int n = as.length;
134     for (int i = 0; i < n; ++i) {
135     Cell a = as[i];
136     if (a != null) {
137     long v = a.value;
138     a.value = 0L;
139     sum += Double.longBitsToDouble(v);
140     }
141     }
142     }
143     return sum;
144     }
145    
146     /**
147     * Returns the String representation of the {@link #sum}.
148 jsr166 1.3 * @return the String representation of the {@link #sum}
149 dl 1.1 */
150     public String toString() {
151     return Double.toString(sum());
152     }
153    
154     /**
155     * Equivalent to {@link #sum}.
156     *
157     * @return the sum
158     */
159     public double doubleValue() {
160     return sum();
161     }
162    
163     /**
164     * Returns the {@link #sum} as a {@code long} after a
165 jsr166 1.4 * narrowing primitive conversion.
166 dl 1.1 */
167     public long longValue() {
168     return (long)sum();
169     }
170    
171     /**
172     * Returns the {@link #sum} as an {@code int} after a
173 jsr166 1.4 * narrowing primitive conversion.
174 dl 1.1 */
175     public int intValue() {
176     return (int)sum();
177     }
178    
179     /**
180     * Returns the {@link #sum} as a {@code float}
181 jsr166 1.4 * after a narrowing primitive conversion.
182 dl 1.1 */
183     public float floatValue() {
184     return (float)sum();
185     }
186    
187     private void writeObject(java.io.ObjectOutputStream s)
188     throws java.io.IOException {
189     s.defaultWriteObject();
190     s.writeDouble(sum());
191     }
192    
193     private void readObject(ObjectInputStream s)
194     throws IOException, ClassNotFoundException {
195     s.defaultReadObject();
196     busy = 0;
197     cells = null;
198     base = Double.doubleToRawLongBits(s.readDouble());
199     }
200    
201     }