mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-10 06:59:05 +00:00
8001666: Add lambda-compatible atomics and accumulators to the ActomicXXX classes
Co-authored-by: Chris Hegarty <chris.hegarty@oracle.com> Reviewed-by: dl, chegar, darcy, goetz
This commit is contained in:
parent
7062898817
commit
dcc8fbec72
@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
/**
|
||||
@ -203,6 +205,92 @@ public class AtomicInteger extends Number implements java.io.Serializable {
|
||||
return getAndAdd(delta) + delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int getAndUpdate(IntUnaryOperator updateFunction) {
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = updateFunction.operateAsInt(prev);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int updateAndGet(IntUnaryOperator updateFunction) {
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = updateFunction.operateAsInt(prev);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int getAndAccumulate(int x,
|
||||
IntBinaryOperator accumulatorFunction) {
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = accumulatorFunction.operateAsInt(prev, x);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int accumulateAndGet(int x,
|
||||
IntBinaryOperator accumulatorFunction) {
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = accumulatorFunction.operateAsInt(prev, x);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current value.
|
||||
* @return the String representation of the current value
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
/**
|
||||
@ -245,6 +247,100 @@ public class AtomicIntegerArray implements java.io.Serializable {
|
||||
return getAndAdd(i, delta) + delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int getAndUpdate(int i, IntUnaryOperator updateFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
int prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = updateFunction.operateAsInt(prev);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int updateAndGet(int i, IntUnaryOperator updateFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
int prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = updateFunction.operateAsInt(prev);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and
|
||||
* given values, returning the previous value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value at index {@code i} as its first
|
||||
* argument, and the given update as the second argument.
|
||||
*
|
||||
* @param i the index
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int getAndAccumulate(int i, int x,
|
||||
IntBinaryOperator accumulatorFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
int prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = accumulatorFunction.operateAsInt(prev, x);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and
|
||||
* given values, returning the updated value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value at index {@code i} as its first
|
||||
* argument, and the given update as the second argument.
|
||||
*
|
||||
* @param i the index
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int accumulateAndGet(int i, int x,
|
||||
IntBinaryOperator accumulatorFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
int prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = accumulatorFunction.operateAsInt(prev, x);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current values of array.
|
||||
* @return the String representation of the current values of array
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
import java.util.function.IntBinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@ -264,6 +266,96 @@ public abstract class AtomicIntegerFieldUpdater<T> {
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the previous
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int getAndUpdate(T obj, IntUnaryOperator updateFunction) {
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = updateFunction.operateAsInt(prev);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the updated
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int updateAndGet(T obj, IntUnaryOperator updateFunction) {
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = updateFunction.operateAsInt(prev);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int getAndAccumulate(T obj, int x,
|
||||
IntBinaryOperator accumulatorFunction) {
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = accumulatorFunction.operateAsInt(prev, x);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final int accumulateAndGet(T obj, int x,
|
||||
IntBinaryOperator accumulatorFunction) {
|
||||
int prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = accumulatorFunction.operateAsInt(prev, x);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard hotspot implementation using intrinsics
|
||||
*/
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
/**
|
||||
@ -217,6 +219,92 @@ public class AtomicLong extends Number implements java.io.Serializable {
|
||||
return getAndAdd(delta) + delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long getAndUpdate(LongUnaryOperator updateFunction) {
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = updateFunction.operateAsLong(prev);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long updateAndGet(LongUnaryOperator updateFunction) {
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = updateFunction.operateAsLong(prev);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long getAndAccumulate(long x,
|
||||
LongBinaryOperator accumulatorFunction) {
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = accumulatorFunction.operateAsLong(prev, x);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long accumulateAndGet(long x,
|
||||
LongBinaryOperator accumulatorFunction) {
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = accumulatorFunction.operateAsLong(prev, x);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current value.
|
||||
* @return the String representation of the current value
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
/**
|
||||
@ -244,6 +246,100 @@ public class AtomicLongArray implements java.io.Serializable {
|
||||
return getAndAdd(i, delta) + delta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long getAndUpdate(int i, LongUnaryOperator updateFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
long prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = updateFunction.operateAsLong(prev);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long updateAndGet(int i, LongUnaryOperator updateFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
long prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = updateFunction.operateAsLong(prev);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and
|
||||
* given values, returning the previous value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value at index {@code i} as its first
|
||||
* argument, and the given update as the second argument.
|
||||
*
|
||||
* @param i the index
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long getAndAccumulate(int i, int x,
|
||||
LongBinaryOperator accumulatorFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
long prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = accumulatorFunction.operateAsLong(prev, x);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and
|
||||
* given values, returning the updated value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value at index {@code i} as its first
|
||||
* argument, and the given update as the second argument.
|
||||
*
|
||||
* @param i the index
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long accumulateAndGet(int i, int x,
|
||||
LongBinaryOperator accumulatorFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
long prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = accumulatorFunction.operateAsLong(prev, x);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current values of array.
|
||||
* @return the String representation of the current values of array
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
import java.util.function.LongUnaryOperator;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@ -267,6 +269,96 @@ public abstract class AtomicLongFieldUpdater<T> {
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the previous
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long getAndUpdate(T obj, LongUnaryOperator updateFunction) {
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = updateFunction.operateAsLong(prev);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the updated
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long updateAndGet(T obj, LongUnaryOperator updateFunction) {
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = updateFunction.operateAsLong(prev);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long getAndAccumulate(T obj, long x,
|
||||
LongBinaryOperator accumulatorFunction) {
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = accumulatorFunction.operateAsLong(prev, x);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final long accumulateAndGet(T obj, long x,
|
||||
LongBinaryOperator accumulatorFunction) {
|
||||
long prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = accumulatorFunction.operateAsLong(prev, x);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
private final long offset;
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.function.BinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
/**
|
||||
@ -141,6 +143,92 @@ public class AtomicReference<V> implements java.io.Serializable {
|
||||
return (V)unsafe.getAndSetObject(this, valueOffset, newValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final V getAndUpdate(UnaryOperator<V> updateFunction) {
|
||||
V prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = updateFunction.operate(prev);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final V updateAndGet(UnaryOperator<V> updateFunction) {
|
||||
V prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = updateFunction.operate(prev);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the previous value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final V getAndAccumulate(V x,
|
||||
BinaryOperator<V> accumulatorFunction) {
|
||||
V prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = accumulatorFunction.operate(prev, x);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the current value with the results of
|
||||
* applying the given function to the current and given values,
|
||||
* returning the updated value. The function should be
|
||||
* side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function
|
||||
* is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final V accumulateAndGet(V x,
|
||||
BinaryOperator<V> accumulatorFunction) {
|
||||
V prev, next;
|
||||
do {
|
||||
prev = get();
|
||||
next = accumulatorFunction.operate(prev, x);
|
||||
} while (!compareAndSet(prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current value.
|
||||
* @return the String representation of the current value
|
||||
|
||||
@ -36,6 +36,8 @@
|
||||
package java.util.concurrent.atomic;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.lang.reflect.Array;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
@ -199,6 +201,100 @@ public class AtomicReferenceArray<E> implements java.io.Serializable {
|
||||
return compareAndSet(i, expect, update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final E getAndUpdate(int i, UnaryOperator<E> updateFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
E prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = updateFunction.operate(prev);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the results
|
||||
* of applying the given function, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param i the index
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final E updateAndGet(int i, UnaryOperator<E> updateFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
E prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = updateFunction.operate(prev);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and
|
||||
* given values, returning the previous value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value at index {@code i} as its first
|
||||
* argument, and the given update as the second argument.
|
||||
*
|
||||
* @param i the index
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final E getAndAccumulate(int i, E x,
|
||||
BinaryOperator<E> accumulatorFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
E prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = accumulatorFunction.operate(prev, x);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the element at index {@code i} with the
|
||||
* results of applying the given function to the current and
|
||||
* given values, returning the updated value. The function should
|
||||
* be side-effect-free, since it may be re-applied when attempted
|
||||
* updates fail due to contention among threads. The function is
|
||||
* applied with the current value at index {@code i} as its first
|
||||
* argument, and the given update as the second argument.
|
||||
*
|
||||
* @param i the index
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final E accumulateAndGet(int i, E x,
|
||||
BinaryOperator<E> accumulatorFunction) {
|
||||
long offset = checkedByteOffset(i);
|
||||
E prev, next;
|
||||
do {
|
||||
prev = getRaw(offset);
|
||||
next = accumulatorFunction.operate(prev, x);
|
||||
} while (!compareAndSetRaw(offset, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String representation of the current values of array.
|
||||
* @return the String representation of the current values of array
|
||||
|
||||
@ -34,6 +34,8 @@
|
||||
*/
|
||||
|
||||
package java.util.concurrent.atomic;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.function.BinaryOperator;
|
||||
import sun.misc.Unsafe;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
@ -183,6 +185,96 @@ public abstract class AtomicReferenceFieldUpdater<T, V> {
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the previous
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final V getAndUpdate(T obj, UnaryOperator<V> updateFunction) {
|
||||
V prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = updateFunction.operate(prev);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this updater
|
||||
* with the results of applying the given function, returning the updated
|
||||
* value. The function should be side-effect-free, since it may be
|
||||
* re-applied when attempted updates fail due to contention among threads.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param updateFunction a side-effect-free function
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final V updateAndGet(T obj, UnaryOperator<V> updateFunction) {
|
||||
V prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = updateFunction.operate(prev);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the previous value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the previous value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final V getAndAccumulate(T obj, V x,
|
||||
BinaryOperator<V> accumulatorFunction) {
|
||||
V prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = accumulatorFunction.operate(prev, x);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return prev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Atomically updates the field of the given object managed by this
|
||||
* updater with the results of applying the given function to the
|
||||
* current and given values, returning the updated value. The
|
||||
* function should be side-effect-free, since it may be re-applied
|
||||
* when attempted updates fail due to contention among threads. The
|
||||
* function is applied with the current value as its first argument,
|
||||
* and the given update as the second argument.
|
||||
*
|
||||
* @param obj An object whose field to get and set
|
||||
* @param x the update value
|
||||
* @param accumulatorFunction a side-effect-free function of two arguments
|
||||
* @return the updated value
|
||||
* @since 1.8
|
||||
*/
|
||||
public final V accumulateAndGet(T obj, V x,
|
||||
BinaryOperator<V> accumulatorFunction) {
|
||||
V prev, next;
|
||||
do {
|
||||
prev = get(obj);
|
||||
next = accumulatorFunction.operate(prev, x);
|
||||
} while (!compareAndSet(obj, prev, next));
|
||||
return next;
|
||||
}
|
||||
|
||||
private static final class AtomicReferenceFieldUpdaterImpl<T,V>
|
||||
extends AtomicReferenceFieldUpdater<T,V> {
|
||||
private static final Unsafe unsafe = Unsafe.getUnsafe();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user