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      */
LongAdder()48     public LongAdder() {
49     }
50 
51     /**
52      * Adds the given value.
53      *
54      * @param x the value to add
55      */
add(long x)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      */
increment()70     public void increment() {
71         add(1L);
72     }
73 
74     /**
75      * Equivalent to {@code add(-1)}.
76      */
decrement()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      */
sum()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      */
reset()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      */
sumThenReset()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      */
toString()147     public String toString() {
148         return Long.toString(sum());
149     }
150 
151     /**
152      * Equivalent to {@link #sum}.
153      *
154      * @return the sum
155      */
longValue()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      */
intValue()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      */
floatValue()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      */
doubleValue()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 
SerializationProxy(LongAdder a)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          */
readResolve()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      */
writeReplace()225     private Object writeReplace() {
226         return new SerializationProxy(this);
227     }
228 
229     /**
230      * @param s the stream
231      * @throws java.io.InvalidObjectException always
232      */
readObject(java.io.ObjectInputStream s)233     private void readObject(java.io.ObjectInputStream s)
234         throws java.io.InvalidObjectException {
235         throw new java.io.InvalidObjectException("Proxy required");
236     }
237 
238 }
239