1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Expert Group and released to the public domain, as explained at 4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent.atomic; 8a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 9a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilsonimport java.lang.reflect.Array; 10e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.Arrays; 11e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.function.BinaryOperator; 12e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniakimport java.util.function.UnaryOperator; 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An array of object references in which elements may be updated 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * atomically. See the {@link java.util.concurrent.atomic} package 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * specification for description of the properties of atomic 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * variables. 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <E> The base class of elements held in this array 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 23bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilsonpublic class AtomicReferenceArray<E> implements java.io.Serializable { 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = -6209656149925076980L; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 26e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final sun.misc.Unsafe U = sun.misc.Unsafe.getUnsafe(); 27e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final long ARRAY; 28e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final int ABASE; 29e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak private static final int ASHIFT; 30a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson private final Object[] array; // must have exact type Object[] 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 328eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson static { 33a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson try { 34e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak ARRAY = U.objectFieldOffset 35a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson (AtomicReferenceArray.class.getDeclaredField("array")); 36e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak ABASE = U.arrayBaseOffset(Object[].class); 37e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak int scale = U.arrayIndexScale(Object[].class); 3891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle if ((scale & (scale - 1)) != 0) 39e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak throw new Error("array index scale not a power of two"); 40e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak ASHIFT = 31 - Integer.numberOfLeadingZeros(scale); 41e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } catch (ReflectiveOperationException e) { 42a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson throw new Error(e); 43a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 448eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson } 458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson 466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private long checkedByteOffset(int i) { 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i < 0 || i >= array.length) 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IndexOutOfBoundsException("index " + i); 496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return byteOffset(i); 516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static long byteOffset(int i) { 54e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return ((long) i << ASHIFT) + ABASE; 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Creates a new AtomicReferenceArray of the given length, with all 59a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * elements initially null. 606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param length the length of the array 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AtomicReferenceArray(int length) { 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project array = new Object[length]; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 68bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Creates a new AtomicReferenceArray with the same length as, and 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * all elements copied from, the given array. 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param array the array to copy elements from 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException if array is null 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public AtomicReferenceArray(E[] array) { 756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Visibility guaranteed by final field guarantees 76a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson this.array = Arrays.copyOf(array, array.length, Object[].class); 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the length of the array. 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the length of the array 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final int length() { 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return array.length; 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Gets the current value at position {@code i}. 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param i the index 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the current value 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final E get(int i) { 956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return getRaw(checkedByteOffset(i)); 966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle @SuppressWarnings("unchecked") 996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private E getRaw(long offset) { 100e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return (E) U.getObjectVolatile(array, offset); 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 102bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 104bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Sets the element at position {@code i} to the given value. 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param i the index 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newValue the new value 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final void set(int i, E newValue) { 110e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak U.putObjectVolatile(array, checkedByteOffset(i), newValue); 1116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 1126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 1146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Eventually sets the element at position {@code i} to the given value. 1156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param i the index 1176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param newValue the new value 1186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @since 1.6 1196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 1206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final void lazySet(int i, E newValue) { 121e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak U.putOrderedObject(array, checkedByteOffset(i), newValue); 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 125bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Atomically sets the element at position {@code i} to the given 126bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * value and returns the old value. 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param i the index 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newValue the new value 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the previous value 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 132e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak @SuppressWarnings("unchecked") 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final E getAndSet(int i, E newValue) { 134e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return (E)U.getAndSetObject(array, checkedByteOffset(i), newValue); 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 136bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 138bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Atomically sets the element at position {@code i} to the given 139bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * updated value if the current value {@code ==} the expected value. 1406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param i the index 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param expect the expected value 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param update the new value 144e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @return {@code true} if successful. False return indicates that 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the actual value was not equal to the expected value. 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final boolean compareAndSet(int i, E expect, E update) { 1486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return compareAndSetRaw(checkedByteOffset(i), expect, update); 1496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 1506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private boolean compareAndSetRaw(long offset, E expect, E update) { 152e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return U.compareAndSwapObject(array, offset, expect, update); 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 156bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Atomically sets the element at position {@code i} to the given 157bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * updated value if the current value {@code ==} the expected value. 158bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 15991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * <p><a href="package-summary.html#weakCompareAndSet">May fail 16091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * spuriously and does not provide ordering guarantees</a>, so is 16191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * only rarely an appropriate alternative to {@code compareAndSet}. 162bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param i the index 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param expect the expected value 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param update the new value 166e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @return {@code true} if successful 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public final boolean weakCompareAndSet(int i, E expect, E update) { 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return compareAndSet(i, expect, update); 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 173e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Atomically updates the element at index {@code i} with the results 174e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * of applying the given function, returning the previous value. The 175e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * function should be side-effect-free, since it may be re-applied 176e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * when attempted updates fail due to contention among threads. 177e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * 178e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param i the index 179e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param updateFunction a side-effect-free function 180e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @return the previous value 181e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @since 1.8 182e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak */ 183e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public final E getAndUpdate(int i, UnaryOperator<E> updateFunction) { 184e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak long offset = checkedByteOffset(i); 185e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak E prev, next; 186e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak do { 187e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak prev = getRaw(offset); 188e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak next = updateFunction.apply(prev); 189e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } while (!compareAndSetRaw(offset, prev, next)); 190e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return prev; 191e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 192e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 193e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** 194e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Atomically updates the element at index {@code i} with the results 195e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * of applying the given function, returning the updated value. The 196e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * function should be side-effect-free, since it may be re-applied 197e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * when attempted updates fail due to contention among threads. 198e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * 199e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param i the index 200e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param updateFunction a side-effect-free function 201e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @return the updated value 202e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @since 1.8 203e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak */ 204e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public final E updateAndGet(int i, UnaryOperator<E> updateFunction) { 205e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak long offset = checkedByteOffset(i); 206e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak E prev, next; 207e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak do { 208e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak prev = getRaw(offset); 209e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak next = updateFunction.apply(prev); 210e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } while (!compareAndSetRaw(offset, prev, next)); 211e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return next; 212e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 213e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 214e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** 215e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Atomically updates the element at index {@code i} with the 216e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * results of applying the given function to the current and 217e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * given values, returning the previous value. The function should 218e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * be side-effect-free, since it may be re-applied when attempted 219e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * updates fail due to contention among threads. The function is 220e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * applied with the current value at index {@code i} as its first 221e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * argument, and the given update as the second argument. 222e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * 223e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param i the index 224e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param x the update value 225e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param accumulatorFunction a side-effect-free function of two arguments 226e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @return the previous value 227e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @since 1.8 228e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak */ 229e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public final E getAndAccumulate(int i, E x, 230e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak BinaryOperator<E> accumulatorFunction) { 231e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak long offset = checkedByteOffset(i); 232e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak E prev, next; 233e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak do { 234e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak prev = getRaw(offset); 235e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak next = accumulatorFunction.apply(prev, x); 236e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } while (!compareAndSetRaw(offset, prev, next)); 237e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return prev; 238e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 239e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 240e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** 241e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * Atomically updates the element at index {@code i} with the 242e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * results of applying the given function to the current and 243e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * given values, returning the updated value. The function should 244e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * be side-effect-free, since it may be re-applied when attempted 245e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * updates fail due to contention among threads. The function is 246e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * applied with the current value at index {@code i} as its first 247e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * argument, and the given update as the second argument. 248e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * 249e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param i the index 250e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param x the update value 251e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param accumulatorFunction a side-effect-free function of two arguments 252e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @return the updated value 253e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @since 1.8 254e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak */ 255e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak public final E accumulateAndGet(int i, E x, 256e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak BinaryOperator<E> accumulatorFunction) { 257e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak long offset = checkedByteOffset(i); 258e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak E prev, next; 259e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak do { 260e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak prev = getRaw(offset); 261e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak next = accumulatorFunction.apply(prev, x); 262e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } while (!compareAndSetRaw(offset, prev, next)); 263e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak return next; 264e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak } 265e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak 266e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak /** 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the String representation of the current values of array. 2686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the String representation of the current values of array 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 271a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson int iMax = array.length - 1; 2726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (iMax == -1) 2736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return "[]"; 2746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson StringBuilder b = new StringBuilder(); 2766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson b.append('['); 2776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (int i = 0; ; i++) { 2786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson b.append(getRaw(byteOffset(i))); 2796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (i == iMax) 2806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return b.append(']').toString(); 2818eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson b.append(',').append(' '); 2826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 285a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson /** 286a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * Reconstitutes the instance from a stream (that is, deserializes it). 287e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @param s the stream 288e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @throws ClassNotFoundException if the class of a serialized object 289e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * could not be found 290e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak * @throws java.io.IOException if an I/O error occurs 291a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson */ 292a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson private void readObject(java.io.ObjectInputStream s) 293e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak throws java.io.IOException, ClassNotFoundException { 294a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson // Note: This must be changed if any additional fields are defined 295a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson Object a = s.readFields().get("array", null); 296a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson if (a == null || !a.getClass().isArray()) 297a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson throw new java.io.InvalidObjectException("Not array type"); 298a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson if (a.getClass() != Object[].class) 299a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson a = Arrays.copyOf((Object[])a, Array.getLength(a), Object[].class); 300e8b323c7cb7d55be9a4df579231e44f04f53d766Przemyslaw Szczepaniak U.putObjectVolatile(this, ARRAY, a); 301a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson } 302a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 304