1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3 *
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Oracle designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Oracle in the LICENSE file that accompanied this code.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 */
24
25 /*
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
29 * file:
30 *
31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 * Expert Group and released to the public domain, as explained at
33 * http://creativecommons.org/publicdomain/zero/1.0/
34 */
35
36 package java.util.concurrent.atomic;
37
38 import java.io.Serializable;
39
40 /**
41 * One or more variables that together maintain an initially zero
42 * {@code long} sum. When updates (method {@link #add}) are contended
43 * across threads, the set of variables may grow dynamically to reduce
44 * contention. Method {@link #sum} (or, equivalently, {@link
45 * #longValue}) returns the current total combined across the
46 * variables maintaining the sum.
47 *
48 * <p>This class is usually preferable to {@link AtomicLong} when
49 * multiple threads update a common sum that is used for purposes such
50 * as collecting statistics, not for fine-grained synchronization
51 * control. Under low update contention, the two classes have similar
52 * characteristics. But under high contention, expected throughput of
53 * this class is significantly higher, at the expense of higher space
54 * consumption.
55 *
56 * <p>LongAdders can be used with a {@link
57 * java.util.concurrent.ConcurrentHashMap} to maintain a scalable
58 * frequency map (a form of histogram or multiset). For example, to
59 * add a count to a {@code ConcurrentHashMap<String,LongAdder> freqs},
60 * initializing if not already present, you can use {@code
61 * freqs.computeIfAbsent(key, k -> new LongAdder()).increment();}
62 *
63 * <p>This class extends {@link Number}, but does <em>not</em> define
64 * methods such as {@code equals}, {@code hashCode} and {@code
65 * compareTo} because instances are expected to be mutated, and so are
66 * not useful as collection keys.
67 *
68 * @since 1.8
69 * @author Doug Lea
70 */
71 public class LongAdder extends Striped64 implements Serializable {
72 private static final long serialVersionUID = 7249069246863182397L;
73
74 /**
75 * Creates a new adder with initial sum of zero.
76 */
77 public LongAdder() {
78 }
79
80 /**
81 * Adds the given value.
82 *
83 * @param x the value to add
84 */
85 public void add(long x) {
86 Cell[] cs; long b, v; int m; Cell c;
87 if ((cs = cells) != null || !casBase(b = base, b + x)) {
88 boolean uncontended = true;
89 if (cs == null || (m = cs.length - 1) < 0 ||
90 (c = cs[getProbe() & m]) == null ||
91 !(uncontended = c.cas(v = c.value, v + x)))
92 longAccumulate(x, null, uncontended);
93 }
94 }
95
96 /**
97 * Equivalent to {@code add(1)}.
98 */
99 public void increment() {
100 add(1L);
101 }
102
103 /**
104 * Equivalent to {@code add(-1)}.
105 */
106 public void decrement() {
107 add(-1L);
108 }
109
110 /**
111 * Returns the current sum. The returned value is <em>NOT</em> an
112 * atomic snapshot; invocation in the absence of concurrent
113 * updates returns an accurate result, but concurrent updates that
114 * occur while the sum is being calculated might not be
115 * incorporated.
116 *
117 * @return the sum
118 */
119 public long sum() {
120 Cell[] cs = cells;
121 long sum = base;
122 if (cs != null) {
123 for (Cell c : cs)
124 if (c != null)
125 sum += c.value;
126 }
127 return sum;
128 }
129
130 /**
131 * Resets variables maintaining the sum to zero. This method may
132 * be a useful alternative to creating a new adder, but is only
133 * effective if there are no concurrent updates. Because this
134 * method is intrinsically racy, it should only be used when it is
135 * known that no threads are concurrently updating.
136 */
137 public void reset() {
138 Cell[] cs = cells;
139 base = 0L;
140 if (cs != null) {
141 for (Cell c : cs)
142 if (c != null)
143 c.reset();
144 }
145 }
146
147 /**
148 * Equivalent in effect to {@link #sum} followed by {@link
149 * #reset}. This method may apply for example during quiescent
150 * points between multithreaded computations. If there are
151 * updates concurrent with this method, the returned value is
152 * <em>not</em> guaranteed to be the final value occurring before
153 * the reset.
154 *
155 * @return the sum
156 */
157 public long sumThenReset() {
158 Cell[] cs = cells;
159 long sum = getAndSetBase(0L);
160 if (cs != null) {
161 for (Cell c : cs) {
162 if (c != null)
163 sum += c.getAndSet(0L);
164 }
165 }
166 return sum;
167 }
168
169 /**
170 * Returns the String representation of the {@link #sum}.
171 * @return the String representation of the {@link #sum}
172 */
173 public String toString() {
174 return Long.toString(sum());
175 }
176
177 /**
178 * Equivalent to {@link #sum}.
179 *
180 * @return the sum
181 */
182 public long longValue() {
183 return sum();
184 }
185
186 /**
187 * Returns the {@link #sum} as an {@code int} after a narrowing
188 * primitive conversion.
189 */
190 public int intValue() {
191 return (int)sum();
192 }
193
194 /**
195 * Returns the {@link #sum} as a {@code float}
196 * after a widening primitive conversion.
197 */
198 public float floatValue() {
199 return (float)sum();
200 }
201
202 /**
203 * Returns the {@link #sum} as a {@code double} after a widening
204 * primitive conversion.
205 */
206 public double doubleValue() {
207 return (double)sum();
208 }
209
210 /**
211 * Serialization proxy, used to avoid reference to the non-public
212 * Striped64 superclass in serialized forms.
213 * @serial include
214 */
215 private static class SerializationProxy implements Serializable {
216 private static final long serialVersionUID = 7249069246863182397L;
217
218 /**
219 * The current value returned by sum().
220 * @serial
221 */
222 private final long value;
223
224 SerializationProxy(LongAdder a) {
225 value = a.sum();
226 }
227
228 /**
229 * Returns a {@code LongAdder} object with initial state
230 * held by this proxy.
231 *
232 * @return a {@code LongAdder} object with initial state
233 * held by this proxy
234 */
235 private Object readResolve() {
236 LongAdder a = new LongAdder();
237 a.base = value;
238 return a;
239 }
240 }
241
242 /**
243 * Returns a
244 * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.LongAdder.SerializationProxy">
245 * SerializationProxy</a>
246 * representing the state of this instance.
247 *
248 * @return a {@link SerializationProxy}
249 * representing the state of this instance
250 */
251 private Object writeReplace() {
252 return new SerializationProxy(this);
253 }
254
255 /**
256 * @param s the stream
257 * @throws java.io.InvalidObjectException always
258 */
259 private void readObject(java.io.ObjectInputStream s)
260 throws java.io.InvalidObjectException {
261 throw new java.io.InvalidObjectException("Proxy required");
262 }
263
264 }
265