ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdder.java
Revision: 1.10
Committed: Sun Nov 18 18:03:10 2012 UTC (11 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.9: +1 -1 lines
Log Message:
normalize whitespace after <p>

File Contents

# Content
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 * 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 *
22 * <p>This class is usually preferable to {@link AtomicLong} when
23 * 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 * <p>This class extends {@link Number}, but does <em>not</em> define
31 * methods such as {@code hashCode} and {@code compareTo} because
32 * instances are expected to be mutated, and so are not useful as
33 * collection keys.
34 *
35 * <p><em>jsr166e note: This class is targeted to be placed in
36 * java.util.concurrent.atomic.</em>
37 *
38 * @since 1.8
39 * @author Doug Lea
40 */
41 public class LongAdder extends Striped64 implements Serializable {
42 private static final long serialVersionUID = 7249069246863182397L;
43
44 /**
45 * Version of plus for use in retryUpdate
46 */
47 final long fn(long v, long x) { return v + x; }
48
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 Cell[] as; long b, v; HashCode hc; Cell a; int n;
62 if ((as = cells) != null || !casBase(b = base, b + x)) {
63 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 !(uncontended = a.cas(v = a.value, v + x)))
68 retryUpdate(x, hc, uncontended);
69 }
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 * Returns the current sum. The returned value is <em>NOT</em> an
88 * atomic snapshot: Invocation in the absence of concurrent
89 * updates returns an accurate result, but concurrent updates that
90 * occur while the sum is being calculated might not be
91 * incorporated.
92 *
93 * @return the sum
94 */
95 public long sum() {
96 long sum = base;
97 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 * 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 */
116 public void reset() {
117 internalReset(0L);
118 }
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 * <em>not</em> guaranteed to be the final value occurring before
126 * the reset.
127 *
128 * @return the sum
129 */
130 public long sumThenReset() {
131 long sum = base;
132 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 sum += a.value;
140 a.value = 0L;
141 }
142 }
143 }
144 return sum;
145 }
146
147 /**
148 * Returns the String representation of the {@link #sum}.
149 * @return the String representation of the {@link #sum}
150 */
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 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 }