ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/DoubleAdder.java
Revision: 1.12
Committed: Mon May 5 20:20:15 2014 UTC (9 years, 11 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.11: +7 -4 lines
Log Message:
import everything to reduce diffs with guava fork

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