ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/DoubleAdder.java
Revision: 1.8
Committed: Mon Jan 7 07:14:01 2013 UTC (11 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.7: +2 -5 lines
Log Message:
consistent style for readObject

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