ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdder.java
Revision: 1.13
Committed: Mon Jan 7 07:14:01 2013 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.12: +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.util.concurrent.atomic.AtomicLong;
9     import java.io.Serializable;
10    
11     /**
12 dl 1.5 * One or more variables that together maintain an initially zero
13     * {@code long} sum. When updates (method {@link #add}) are contended
14     * across threads, the set of variables may grow dynamically to reduce
15     * contention. Method {@link #sum} (or, equivalently, {@link
16     * #longValue}) returns the current total combined across the
17     * variables maintaining the sum.
18 dl 1.1 *
19 jsr166 1.10 * <p>This class is usually preferable to {@link AtomicLong} when
20 dl 1.1 * multiple threads update a common sum that is used for purposes such
21     * as collecting statistics, not for fine-grained synchronization
22     * control. Under low update contention, the two classes have similar
23     * characteristics. But under high contention, expected throughput of
24     * this class is significantly higher, at the expense of higher space
25     * consumption.
26     *
27 dl 1.5 * <p>This class extends {@link Number}, but does <em>not</em> define
28 jsr166 1.11 * 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 dl 1.1 *
32     * <p><em>jsr166e note: This class is targeted to be placed in
33 jsr166 1.9 * java.util.concurrent.atomic.</em>
34 dl 1.1 *
35 jsr166 1.7 * @since 1.8
36 dl 1.1 * @author Doug Lea
37     */
38 dl 1.5 public class LongAdder extends Striped64 implements Serializable {
39 dl 1.1 private static final long serialVersionUID = 7249069246863182397L;
40    
41     /**
42 dl 1.5 * Version of plus for use in retryUpdate
43 dl 1.1 */
44 dl 1.5 final long fn(long v, long x) { return v + x; }
45 dl 1.1
46     /**
47     * Creates a new adder with initial sum of zero.
48     */
49     public LongAdder() {
50     }
51    
52     /**
53     * Adds the given value.
54     *
55     * @param x the value to add
56     */
57     public void add(long x) {
58 dl 1.5 Cell[] as; long b, v; HashCode hc; Cell a; int n;
59     if ((as = cells) != null || !casBase(b = base, b + x)) {
60 dl 1.1 boolean uncontended = true;
61     int h = (hc = threadHashCode.get()).code;
62     if (as == null || (n = as.length) < 1 ||
63     (a = as[(n - 1) & h]) == null ||
64 dl 1.5 !(uncontended = a.cas(v = a.value, v + x)))
65     retryUpdate(x, hc, uncontended);
66 dl 1.1 }
67     }
68    
69     /**
70     * Equivalent to {@code add(1)}.
71     */
72     public void increment() {
73     add(1L);
74     }
75    
76     /**
77     * Equivalent to {@code add(-1)}.
78     */
79     public void decrement() {
80     add(-1L);
81     }
82    
83     /**
84 dl 1.5 * Returns the current sum. The returned value is <em>NOT</em> an
85 jsr166 1.12 * atomic snapshot: invocation in the absence of concurrent
86 dl 1.5 * updates returns an accurate result, but concurrent updates that
87     * occur while the sum is being calculated might not be
88     * incorporated.
89 dl 1.1 *
90     * @return the sum
91     */
92     public long sum() {
93 dl 1.6 long sum = base;
94 dl 1.1 Cell[] as = cells;
95     if (as != null) {
96     int n = as.length;
97     for (int i = 0; i < n; ++i) {
98     Cell a = as[i];
99     if (a != null)
100     sum += a.value;
101     }
102     }
103     return sum;
104     }
105    
106     /**
107 dl 1.5 * Resets variables maintaining the sum to zero. This method may
108     * be a useful alternative to creating a new adder, but is only
109     * effective if there are no concurrent updates. Because this
110     * method is intrinsically racy, it should only be used when it is
111     * known that no threads are concurrently updating.
112 dl 1.1 */
113     public void reset() {
114 dl 1.5 internalReset(0L);
115 dl 1.1 }
116    
117     /**
118     * Equivalent in effect to {@link #sum} followed by {@link
119     * #reset}. This method may apply for example during quiescent
120     * points between multithreaded computations. If there are
121     * updates concurrent with this method, the returned value is
122 dl 1.5 * <em>not</em> guaranteed to be the final value occurring before
123 dl 1.1 * the reset.
124     *
125     * @return the sum
126     */
127     public long sumThenReset() {
128 dl 1.6 long sum = base;
129 dl 1.1 Cell[] as = cells;
130     base = 0L;
131     if (as != null) {
132     int n = as.length;
133     for (int i = 0; i < n; ++i) {
134     Cell a = as[i];
135     if (a != null) {
136 dl 1.6 sum += a.value;
137 dl 1.1 a.value = 0L;
138     }
139     }
140     }
141     return sum;
142     }
143    
144 dl 1.5 /**
145     * Returns the String representation of the {@link #sum}.
146 jsr166 1.8 * @return the String representation of the {@link #sum}
147 dl 1.5 */
148     public String toString() {
149     return Long.toString(sum());
150     }
151    
152     /**
153     * Equivalent to {@link #sum}.
154     *
155     * @return the sum
156     */
157     public long longValue() {
158     return sum();
159     }
160    
161     /**
162     * Returns the {@link #sum} as an {@code int} after a narrowing
163     * primitive conversion.
164     */
165     public int intValue() {
166     return (int)sum();
167     }
168    
169     /**
170     * Returns the {@link #sum} as a {@code float}
171     * after a widening primitive conversion.
172     */
173     public float floatValue() {
174     return (float)sum();
175     }
176    
177     /**
178     * Returns the {@link #sum} as a {@code double} after a widening
179     * primitive conversion.
180     */
181     public double doubleValue() {
182     return (double)sum();
183     }
184    
185 dl 1.1 private void writeObject(java.io.ObjectOutputStream s)
186     throws java.io.IOException {
187     s.defaultWriteObject();
188     s.writeLong(sum());
189     }
190    
191 jsr166 1.13 private void readObject(java.io.ObjectInputStream s)
192     throws java.io.IOException, ClassNotFoundException {
193 dl 1.1 s.defaultReadObject();
194     busy = 0;
195     cells = null;
196     base = s.readLong();
197     }
198    
199     }