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
36package java.util.concurrent.atomic;
37
38import java.io.Serializable;
39import java.util.function.LongBinaryOperator;
40
41/**
42 * One or more variables that together maintain a running {@code long}
43 * value updated using a supplied function.  When updates (method
44 * {@link #accumulate}) are contended across threads, the set of variables
45 * may grow dynamically to reduce contention.  Method {@link #get}
46 * (or, equivalently, {@link #longValue}) returns the current value
47 * across the variables maintaining updates.
48 *
49 * <p>This class is usually preferable to {@link AtomicLong} when
50 * multiple threads update a common value that is used for purposes such
51 * as collecting statistics, not for fine-grained synchronization
52 * control.  Under low update contention, the two classes have similar
53 * characteristics. But under high contention, expected throughput of
54 * this class is significantly higher, at the expense of higher space
55 * consumption.
56 *
57 * <p>The order of accumulation within or across threads is not
58 * guaranteed and cannot be depended upon, so this class is only
59 * applicable to functions for which the order of accumulation does
60 * not matter. The supplied accumulator function should be
61 * side-effect-free, since it may be re-applied when attempted updates
62 * fail due to contention among threads. The function is applied with
63 * the current value as its first argument, and the given update as
64 * the second argument.  For example, to maintain a running maximum
65 * value, you could supply {@code Long::max} along with {@code
66 * Long.MIN_VALUE} as the identity.
67 *
68 * <p>Class {@link LongAdder} provides analogs of the functionality of
69 * this class for the common special case of maintaining counts and
70 * sums.  The call {@code new LongAdder()} is equivalent to {@code new
71 * LongAccumulator((x, y) -> x + y, 0L)}.
72 *
73 * <p>This class extends {@link Number}, but does <em>not</em> define
74 * methods such as {@code equals}, {@code hashCode} and {@code
75 * compareTo} because instances are expected to be mutated, and so are
76 * not useful as collection keys.
77 *
78 * @since 1.8
79 * @author Doug Lea
80 */
81public class LongAccumulator extends Striped64 implements Serializable {
82    private static final long serialVersionUID = 7249069246863182397L;
83
84    private final LongBinaryOperator function;
85    private final long identity;
86
87    /**
88     * Creates a new instance using the given accumulator function
89     * and identity element.
90     * @param accumulatorFunction a side-effect-free function of two arguments
91     * @param identity identity (initial value) for the accumulator function
92     */
93    public LongAccumulator(LongBinaryOperator accumulatorFunction,
94                           long identity) {
95        this.function = accumulatorFunction;
96        base = this.identity = identity;
97    }
98
99    /**
100     * Updates with the given value.
101     *
102     * @param x the value
103     */
104    public void accumulate(long x) {
105        Cell[] as; long b, v, r; int m; Cell a;
106        if ((as = cells) != null
107            || ((r = function.applyAsLong(b = base, x)) != b
108                && !casBase(b, r))) {
109            boolean uncontended = true;
110            if (as == null
111                || (m = as.length - 1) < 0
112                || (a = as[getProbe() & m]) == null
113                || !(uncontended =
114                     (r = function.applyAsLong(v = a.value, x)) == v
115                     || a.cas(v, r)))
116                longAccumulate(x, function, uncontended);
117        }
118    }
119
120    /**
121     * Returns the current value.  The returned value is <em>NOT</em>
122     * an atomic snapshot; invocation in the absence of concurrent
123     * updates returns an accurate result, but concurrent updates that
124     * occur while the value is being calculated might not be
125     * incorporated.
126     *
127     * @return the current value
128     */
129    public long get() {
130        Cell[] as = cells;
131        long result = base;
132        if (as != null) {
133            for (Cell a : as)
134                if (a != null)
135                    result = function.applyAsLong(result, a.value);
136        }
137        return result;
138    }
139
140    /**
141     * Resets variables maintaining updates to the identity value.
142     * This method may be a useful alternative to creating a new
143     * updater, but is only effective if there are no concurrent
144     * updates.  Because this method is intrinsically racy, it should
145     * only be used when it is known that no threads are concurrently
146     * updating.
147     */
148    public void reset() {
149        Cell[] as = cells;
150        base = identity;
151        if (as != null) {
152            for (Cell a : as)
153                if (a != null)
154                    a.reset(identity);
155        }
156    }
157
158    /**
159     * Equivalent in effect to {@link #get} followed by {@link
160     * #reset}. This method may apply for example during quiescent
161     * points between multithreaded computations.  If there are
162     * updates concurrent with this method, the returned value is
163     * <em>not</em> guaranteed to be the final value occurring before
164     * the reset.
165     *
166     * @return the value before reset
167     */
168    public long getThenReset() {
169        Cell[] as = cells;
170        long result = base;
171        base = identity;
172        if (as != null) {
173            for (Cell a : as) {
174                if (a != null) {
175                    long v = a.value;
176                    a.reset(identity);
177                    result = function.applyAsLong(result, v);
178                }
179            }
180        }
181        return result;
182    }
183
184    /**
185     * Returns the String representation of the current value.
186     * @return the String representation of the current value
187     */
188    public String toString() {
189        return Long.toString(get());
190    }
191
192    /**
193     * Equivalent to {@link #get}.
194     *
195     * @return the current value
196     */
197    public long longValue() {
198        return get();
199    }
200
201    /**
202     * Returns the {@linkplain #get current value} as an {@code int}
203     * after a narrowing primitive conversion.
204     */
205    public int intValue() {
206        return (int)get();
207    }
208
209    /**
210     * Returns the {@linkplain #get current value} as a {@code float}
211     * after a widening primitive conversion.
212     */
213    public float floatValue() {
214        return (float)get();
215    }
216
217    /**
218     * Returns the {@linkplain #get current value} as a {@code double}
219     * after a widening primitive conversion.
220     */
221    public double doubleValue() {
222        return (double)get();
223    }
224
225    /**
226     * Serialization proxy, used to avoid reference to the non-public
227     * Striped64 superclass in serialized forms.
228     * @serial include
229     */
230    private static class SerializationProxy implements Serializable {
231        private static final long serialVersionUID = 7249069246863182397L;
232
233        /**
234         * The current value returned by get().
235         * @serial
236         */
237        private final long value;
238
239        /**
240         * The function used for updates.
241         * @serial
242         */
243        private final LongBinaryOperator function;
244
245        /**
246         * The identity value.
247         * @serial
248         */
249        private final long identity;
250
251        SerializationProxy(long value,
252                           LongBinaryOperator function,
253                           long identity) {
254            this.value = value;
255            this.function = function;
256            this.identity = identity;
257        }
258
259        /**
260         * Returns a {@code LongAccumulator} object with initial state
261         * held by this proxy.
262         *
263         * @return a {@code LongAccumulator} object with initial state
264         * held by this proxy
265         */
266        private Object readResolve() {
267            LongAccumulator a = new LongAccumulator(function, identity);
268            a.base = value;
269            return a;
270        }
271    }
272
273    /**
274     * Returns a
275     * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.LongAccumulator.SerializationProxy">
276     * SerializationProxy</a>
277     * representing the state of this instance.
278     *
279     * @return a {@link SerializationProxy}
280     * representing the state of this instance
281     */
282    private Object writeReplace() {
283        return new SerializationProxy(get(), function, identity);
284    }
285
286    /**
287     * @param s the stream
288     * @throws java.io.InvalidObjectException always
289     */
290    private void readObject(java.io.ObjectInputStream s)
291        throws java.io.InvalidObjectException {
292        throw new java.io.InvalidObjectException("Proxy required");
293    }
294
295}
296