1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is free software; you can redistribute it and/or modify it
529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * under the terms of the GNU General Public License version 2 only, as
629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * published by the Free Software Foundation.  Oracle designates this
729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * particular file as subject to the "Classpath" exception as provided
829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * by Oracle in the LICENSE file that accompanied this code.
929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
1029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This code is distributed in the hope that it will be useful, but WITHOUT
1129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * version 2 for more details (a copy is included in the LICENSE file that
1429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * accompanied this code).
1529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
1629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * You should have received a copy of the GNU General Public License version
1729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * 2 along with this work; if not, write to the Free Software Foundation,
1829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
2029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2129957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * or visit www.oracle.com if you need additional information or have any
2229957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * questions.
2329957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer */
2429957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer
2529957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer/*
2629957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * This file is available under and governed by the GNU General Public
2729957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * License version 2 only, as published by the Free Software Foundation.
2829957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * However, the following notice accompanied the original version of this
2929957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer * file:
3029957558cf0db700bfaae360a80c42dc3871d0e5Tobias Thierer *
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at
33a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent.atomic;
37edf43d27e240d82106f39ae91404963c23987234Narayan Kamath
38b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.function.BinaryOperator;
39b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniakimport java.util.function.UnaryOperator;
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An object reference that may be updated atomically. See the {@link
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * java.util.concurrent.atomic} package specification for description
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the properties of atomic variables.
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <V> The type of object referred to by this reference
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
4991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravlepublic class AtomicReference<V> implements java.io.Serializable {
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = -1848883965231344442L;
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
52b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe();
53b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    private static final long VALUE;
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    static {
56a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        try {
57b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            VALUE = U.objectFieldOffset
58a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson                (AtomicReference.class.getDeclaredField("value"));
59b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } catch (ReflectiveOperationException e) {
60b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            throw new Error(e);
61b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        }
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private volatile V value;
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
67bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a new AtomicReference with the given initial value.
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param initialValue the initial value
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public AtomicReference(V initialValue) {
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        value = initialValue;
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
76bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Creates a new AtomicReference with null initial value.
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public AtomicReference() {
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
80bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
82bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Gets the current value.
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the current value
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final V get() {
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return value;
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Sets to the given value.
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newValue the new value
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void set(V newValue) {
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        value = newValue;
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
98bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
1006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * Eventually sets to the given value.
1016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     *
1026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @param newValue the new value
1036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     * @since 1.6
1046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson     */
1056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    public final void lazySet(V newValue) {
106b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        U.putOrderedObject(this, VALUE, newValue);
1076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    }
1086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson
1096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson    /**
110bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the value to the given updated value
111bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * if the current value {@code ==} the expected value.
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param expect the expected value
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param update the new value
114b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @return {@code true} if successful. False return indicates that
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the actual value was not equal to the expected value.
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final boolean compareAndSet(V expect, V update) {
118b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return U.compareAndSwapObject(this, VALUE, expect, update);
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
122bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets the value to the given updated value
123bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * if the current value {@code ==} the expected value.
124bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
12591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * <p><a href="package-summary.html#weakCompareAndSet">May fail
12691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * spuriously and does not provide ordering guarantees</a>, so is
12791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * only rarely an appropriate alternative to {@code compareAndSet}.
128bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param expect the expected value
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param update the new value
131b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @return {@code true} if successful
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final boolean weakCompareAndSet(V expect, V update) {
134b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return U.compareAndSwapObject(this, VALUE, expect, update);
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
138bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Atomically sets to the given value and returns the old value.
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param newValue the new value
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the previous value
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
143b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    @SuppressWarnings("unchecked")
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final V getAndSet(V newValue) {
145b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return (V)U.getAndSetObject(this, VALUE, newValue);
146b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
147b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
148b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
149b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Atomically updates the current value with the results of
150b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * applying the given function, returning the previous value. The
151b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * function should be side-effect-free, since it may be re-applied
152b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * when attempted updates fail due to contention among threads.
153b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
154b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @param updateFunction a side-effect-free function
155b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @return the previous value
156b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @since 1.8
157b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
158b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public final V getAndUpdate(UnaryOperator<V> updateFunction) {
159b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        V prev, next;
160b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        do {
161b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            prev = get();
162b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            next = updateFunction.apply(prev);
163b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } while (!compareAndSet(prev, next));
164b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return prev;
165b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
166b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
167b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
168b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Atomically updates the current value with the results of
169b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * applying the given function, returning the updated value. The
170b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * function should be side-effect-free, since it may be re-applied
171b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * when attempted updates fail due to contention among threads.
172b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
173b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @param updateFunction a side-effect-free function
174b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @return the updated value
175b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @since 1.8
176b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
177b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public final V updateAndGet(UnaryOperator<V> updateFunction) {
178b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        V prev, next;
179b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        do {
180b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            prev = get();
181b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            next = updateFunction.apply(prev);
182b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } while (!compareAndSet(prev, next));
183b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return next;
184b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
185b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
186b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
187b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Atomically updates the current value with the results of
188b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * applying the given function to the current and given values,
189b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * returning the previous value. The function should be
190b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * side-effect-free, since it may be re-applied when attempted
191b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * updates fail due to contention among threads.  The function
192b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * is applied with the current value as its first argument,
193b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * and the given update as the second argument.
194b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
195b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @param x the update value
196b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @param accumulatorFunction a side-effect-free function of two arguments
197b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @return the previous value
198b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @since 1.8
199b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
200b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public final V getAndAccumulate(V x,
201b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                                    BinaryOperator<V> accumulatorFunction) {
202b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        V prev, next;
203b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        do {
204b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            prev = get();
205b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            next = accumulatorFunction.apply(prev, x);
206b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } while (!compareAndSet(prev, next));
207b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return prev;
208b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    }
209b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak
210b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    /**
211b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * Atomically updates the current value with the results of
212b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * applying the given function to the current and given values,
213b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * returning the updated value. The function should be
214b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * side-effect-free, since it may be re-applied when attempted
215b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * updates fail due to contention among threads.  The function
216b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * is applied with the current value as its first argument,
217b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * and the given update as the second argument.
218b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     *
219b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @param x the update value
220b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @param accumulatorFunction a side-effect-free function of two arguments
221b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @return the updated value
222b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     * @since 1.8
223b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak     */
224b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak    public final V accumulateAndGet(V x,
225b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak                                    BinaryOperator<V> accumulatorFunction) {
226b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        V prev, next;
227b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        do {
228b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            prev = get();
229b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak            next = accumulatorFunction.apply(prev, x);
230b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        } while (!compareAndSet(prev, next));
231b8b75116273ecfdb8ffdd1869b1c0dd04570a95ePrzemyslaw Szczepaniak        return next;
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the String representation of the current value.
23691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return the String representation of the current value
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public String toString() {
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return String.valueOf(get());
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
243