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 && !casBase(b, r)) {
108            boolean uncontended = true;
109            if (as == null || (m = as.length - 1) < 0 ||
110                (a = as[getProbe() & m]) == null ||
111                !(uncontended =
112                  (r = function.applyAsLong(v = a.value, x)) == v ||
113                  a.cas(v, r)))
114                longAccumulate(x, function, uncontended);
115        }
116    }
117
118    /**
119     * Returns the current value.  The returned value is <em>NOT</em>
120     * an atomic snapshot; invocation in the absence of concurrent
121     * updates returns an accurate result, but concurrent updates that
122     * occur while the value is being calculated might not be
123     * incorporated.
124     *
125     * @return the current value
126     */
127    public long get() {
128        Cell[] as = cells;
129        long result = base;
130        if (as != null) {
131            for (Cell a : as)
132                if (a != null)
133                    result = function.applyAsLong(result, a.value);
134        }
135        return result;
136    }
137
138    /**
139     * Resets variables maintaining updates to the identity value.
140     * This method may be a useful alternative to creating a new
141     * updater, but is only effective if there are no concurrent
142     * updates.  Because this method is intrinsically racy, it should
143     * only be used when it is known that no threads are concurrently
144     * updating.
145     */
146    public void reset() {
147        Cell[] as = cells;
148        base = identity;
149        if (as != null) {
150            for (Cell a : as)
151                if (a != null)
152                    a.reset(identity);
153        }
154    }
155
156    /**
157     * Equivalent in effect to {@link #get} followed by {@link
158     * #reset}. This method may apply for example during quiescent
159     * points between multithreaded computations.  If there are
160     * updates concurrent with this method, the returned value is
161     * <em>not</em> guaranteed to be the final value occurring before
162     * the reset.
163     *
164     * @return the value before reset
165     */
166    public long getThenReset() {
167        Cell[] as = cells;
168        long result = base;
169        base = identity;
170        if (as != null) {
171            for (Cell a : as) {
172                if (a != null) {
173                    long v = a.value;
174                    a.reset(identity);
175                    result = function.applyAsLong(result, v);
176                }
177            }
178        }
179        return result;
180    }
181
182    /**
183     * Returns the String representation of the current value.
184     * @return the String representation of the current value
185     */
186    public String toString() {
187        return Long.toString(get());
188    }
189
190    /**
191     * Equivalent to {@link #get}.
192     *
193     * @return the current value
194     */
195    public long longValue() {
196        return get();
197    }
198
199    /**
200     * Returns the {@linkplain #get current value} as an {@code int}
201     * after a narrowing primitive conversion.
202     */
203    public int intValue() {
204        return (int)get();
205    }
206
207    /**
208     * Returns the {@linkplain #get current value} as a {@code float}
209     * after a widening primitive conversion.
210     */
211    public float floatValue() {
212        return (float)get();
213    }
214
215    /**
216     * Returns the {@linkplain #get current value} as a {@code double}
217     * after a widening primitive conversion.
218     */
219    public double doubleValue() {
220        return (double)get();
221    }
222
223    /**
224     * Serialization proxy, used to avoid reference to the non-public
225     * Striped64 superclass in serialized forms.
226     * @serial include
227     */
228    private static class SerializationProxy implements Serializable {
229        private static final long serialVersionUID = 7249069246863182397L;
230
231        /**
232         * The current value returned by get().
233         * @serial
234         */
235        private final long value;
236
237        /**
238         * The function used for updates.
239         * @serial
240         */
241        private final LongBinaryOperator function;
242
243        /**
244         * The identity value.
245         * @serial
246         */
247        private final long identity;
248
249        SerializationProxy(long value,
250                           LongBinaryOperator function,
251                           long identity) {
252            this.value = value;
253            this.function = function;
254            this.identity = identity;
255        }
256
257        /**
258         * Returns a {@code LongAccumulator} object with initial state
259         * held by this proxy.
260         *
261         * @return a {@code LongAccumulator} object with initial state
262         * held by this proxy
263         */
264        private Object readResolve() {
265            LongAccumulator a = new LongAccumulator(function, identity);
266            a.base = value;
267            return a;
268        }
269    }
270
271    /**
272     * Returns a
273     * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.LongAccumulator.SerializationProxy">
274     * SerializationProxy</a>
275     * representing the state of this instance.
276     *
277     * @return a {@link SerializationProxy}
278     * representing the state of this instance
279     */
280    private Object writeReplace() {
281        return new SerializationProxy(get(), function, identity);
282    }
283
284    /**
285     * @param s the stream
286     * @throws java.io.InvalidObjectException always
287     */
288    private void readObject(java.io.ObjectInputStream s)
289        throws java.io.InvalidObjectException {
290        throw new java.io.InvalidObjectException("Proxy required");
291    }
292
293}
294