ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdder.java
Revision: 1.12
Committed: Sun Jan 6 18:50:00 2013 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.11: +1 -1 lines
Log Message:
javadoc style

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