ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jdk8/java/util/concurrent/atomic/LongAdder.java
Revision: 1.1
Committed: Sat Mar 26 06:22:51 2016 UTC (8 years, 2 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Log Message:
fork jdk8 maintenance branch for source and jtreg tests

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 java.util.concurrent.atomic;
8
9 import java.io.Serializable;
10
11 /**
12 * 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 *
19 * <p>This class is usually preferable to {@link AtomicLong} when
20 * 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 * <p>LongAdders can be used with a {@link
28 * java.util.concurrent.ConcurrentHashMap} to maintain a scalable
29 * frequency map (a form of histogram or multiset). For example, to
30 * add a count to a {@code ConcurrentHashMap<String,LongAdder> freqs},
31 * initializing if not already present, you can use {@code
32 * freqs.computeIfAbsent(key, k -> new LongAdder()).increment();}
33 *
34 * <p>This class extends {@link Number}, but does <em>not</em> define
35 * methods such as {@code equals}, {@code hashCode} and {@code
36 * compareTo} because instances are expected to be mutated, and so are
37 * not useful as collection keys.
38 *
39 * @since 1.8
40 * @author Doug Lea
41 */
42 public class LongAdder extends Striped64 implements Serializable {
43 private static final long serialVersionUID = 7249069246863182397L;
44
45 /**
46 * Creates a new adder with initial sum of zero.
47 */
48 public LongAdder() {
49 }
50
51 /**
52 * Adds the given value.
53 *
54 * @param x the value to add
55 */
56 public void add(long x) {
57 Cell[] as; long b, v; int m; Cell a;
58 if ((as = cells) != null || !casBase(b = base, b + x)) {
59 boolean uncontended = true;
60 if (as == null || (m = as.length - 1) < 0 ||
61 (a = as[getProbe() & m]) == null ||
62 !(uncontended = a.cas(v = a.value, v + x)))
63 longAccumulate(x, null, uncontended);
64 }
65 }
66
67 /**
68 * Equivalent to {@code add(1)}.
69 */
70 public void increment() {
71 add(1L);
72 }
73
74 /**
75 * Equivalent to {@code add(-1)}.
76 */
77 public void decrement() {
78 add(-1L);
79 }
80
81 /**
82 * Returns the current sum. The returned value is <em>NOT</em> an
83 * atomic snapshot; invocation in the absence of concurrent
84 * updates returns an accurate result, but concurrent updates that
85 * occur while the sum is being calculated might not be
86 * incorporated.
87 *
88 * @return the sum
89 */
90 public long sum() {
91 Cell[] as = cells;
92 long sum = base;
93 if (as != null) {
94 for (Cell a : as)
95 if (a != null)
96 sum += a.value;
97 }
98 return sum;
99 }
100
101 /**
102 * Resets variables maintaining the sum to zero. This method may
103 * be a useful alternative to creating a new adder, but is only
104 * effective if there are no concurrent updates. Because this
105 * method is intrinsically racy, it should only be used when it is
106 * known that no threads are concurrently updating.
107 */
108 public void reset() {
109 Cell[] as = cells;
110 base = 0L;
111 if (as != null) {
112 for (Cell a : as)
113 if (a != null)
114 a.reset();
115 }
116 }
117
118 /**
119 * Equivalent in effect to {@link #sum} followed by {@link
120 * #reset}. This method may apply for example during quiescent
121 * points between multithreaded computations. If there are
122 * updates concurrent with this method, the returned value is
123 * <em>not</em> guaranteed to be the final value occurring before
124 * the reset.
125 *
126 * @return the sum
127 */
128 public long sumThenReset() {
129 Cell[] as = cells;
130 long sum = base;
131 base = 0L;
132 if (as != null) {
133 for (Cell a : as) {
134 if (a != null) {
135 sum += a.value;
136 a.reset();
137 }
138 }
139 }
140 return sum;
141 }
142
143 /**
144 * Returns the String representation of the {@link #sum}.
145 * @return the String representation of the {@link #sum}
146 */
147 public String toString() {
148 return Long.toString(sum());
149 }
150
151 /**
152 * Equivalent to {@link #sum}.
153 *
154 * @return the sum
155 */
156 public long longValue() {
157 return sum();
158 }
159
160 /**
161 * Returns the {@link #sum} as an {@code int} after a narrowing
162 * primitive conversion.
163 */
164 public int intValue() {
165 return (int)sum();
166 }
167
168 /**
169 * Returns the {@link #sum} as a {@code float}
170 * after a widening primitive conversion.
171 */
172 public float floatValue() {
173 return (float)sum();
174 }
175
176 /**
177 * Returns the {@link #sum} as a {@code double} after a widening
178 * primitive conversion.
179 */
180 public double doubleValue() {
181 return (double)sum();
182 }
183
184 /**
185 * Serialization proxy, used to avoid reference to the non-public
186 * Striped64 superclass in serialized forms.
187 * @serial include
188 */
189 private static class SerializationProxy implements Serializable {
190 private static final long serialVersionUID = 7249069246863182397L;
191
192 /**
193 * The current value returned by sum().
194 * @serial
195 */
196 private final long value;
197
198 SerializationProxy(LongAdder a) {
199 value = a.sum();
200 }
201
202 /**
203 * Returns a {@code LongAdder} object with initial state
204 * held by this proxy.
205 *
206 * @return a {@code LongAdder} object with initial state
207 * held by this proxy
208 */
209 private Object readResolve() {
210 LongAdder a = new LongAdder();
211 a.base = value;
212 return a;
213 }
214 }
215
216 /**
217 * Returns a
218 * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.LongAdder.SerializationProxy">
219 * SerializationProxy</a>
220 * representing the state of this instance.
221 *
222 * @return a {@link SerializationProxy}
223 * representing the state of this instance
224 */
225 private Object writeReplace() {
226 return new SerializationProxy(this);
227 }
228
229 /**
230 * @param s the stream
231 * @throws java.io.InvalidObjectException always
232 */
233 private void readObject(java.io.ObjectInputStream s)
234 throws java.io.InvalidObjectException {
235 throw new java.io.InvalidObjectException("Proxy required");
236 }
237
238 }