src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java

Print this page




  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 
  36 package java.util.concurrent.atomic;
  37 
  38 import java.util.Arrays;


  39 import java.lang.reflect.Array;
  40 import sun.misc.Unsafe;
  41 
  42 /**
  43  * An array of object references in which elements may be updated
  44  * atomically.  See the {@link java.util.concurrent.atomic} package
  45  * specification for description of the properties of atomic
  46  * variables.
  47  * @since 1.5
  48  * @author Doug Lea
  49  * @param <E> The base class of elements held in this array
  50  */
  51 public class AtomicReferenceArray<E> implements java.io.Serializable {
  52     private static final long serialVersionUID = -6209656149925076980L;
  53 
  54     private static final Unsafe unsafe;
  55     private static final int base;
  56     private static final int shift;
  57     private static final long arrayFieldOffset;
  58     private final Object[] array; // must have exact type Object[]


 182         return unsafe.compareAndSwapObject(array, offset, expect, update);
 183     }
 184 
 185     /**
 186      * Atomically sets the element at position {@code i} to the given
 187      * updated value if the current value {@code ==} the expected value.
 188      *
 189      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
 190      * and does not provide ordering guarantees, so is only rarely an
 191      * appropriate alternative to {@code compareAndSet}.
 192      *
 193      * @param i the index
 194      * @param expect the expected value
 195      * @param update the new value
 196      * @return true if successful
 197      */
 198     public final boolean weakCompareAndSet(int i, E expect, E update) {
 199         return compareAndSet(i, expect, update);
 200     }
 201 






























































































 202     /**
 203      * Returns the String representation of the current values of array.
 204      * @return the String representation of the current values of array
 205      */
 206     public String toString() {
 207         int iMax = array.length - 1;
 208         if (iMax == -1)
 209             return "[]";
 210 
 211         StringBuilder b = new StringBuilder();
 212         b.append('[');
 213         for (int i = 0; ; i++) {
 214             b.append(getRaw(byteOffset(i)));
 215             if (i == iMax)
 216                 return b.append(']').toString();
 217             b.append(',').append(' ');
 218         }
 219     }
 220 
 221     /**


  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 
  36 package java.util.concurrent.atomic;
  37 
  38 import java.util.Arrays;
  39 import java.util.function.UnaryOperator;
  40 import java.util.function.BinaryOperator;
  41 import java.lang.reflect.Array;
  42 import sun.misc.Unsafe;
  43 
  44 /**
  45  * An array of object references in which elements may be updated
  46  * atomically.  See the {@link java.util.concurrent.atomic} package
  47  * specification for description of the properties of atomic
  48  * variables.
  49  * @since 1.5
  50  * @author Doug Lea
  51  * @param <E> The base class of elements held in this array
  52  */
  53 public class AtomicReferenceArray<E> implements java.io.Serializable {
  54     private static final long serialVersionUID = -6209656149925076980L;
  55 
  56     private static final Unsafe unsafe;
  57     private static final int base;
  58     private static final int shift;
  59     private static final long arrayFieldOffset;
  60     private final Object[] array; // must have exact type Object[]


 184         return unsafe.compareAndSwapObject(array, offset, expect, update);
 185     }
 186 
 187     /**
 188      * Atomically sets the element at position {@code i} to the given
 189      * updated value if the current value {@code ==} the expected value.
 190      *
 191      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
 192      * and does not provide ordering guarantees, so is only rarely an
 193      * appropriate alternative to {@code compareAndSet}.
 194      *
 195      * @param i the index
 196      * @param expect the expected value
 197      * @param update the new value
 198      * @return true if successful
 199      */
 200     public final boolean weakCompareAndSet(int i, E expect, E update) {
 201         return compareAndSet(i, expect, update);
 202     }
 203 
 204       /**
 205      * Atomically updates the element at index {@code i} with the results
 206      * of applying the given function. The function should be
 207      * side-effect-free, since it may be re-applied when attempted
 208      * updates fail due to contention among threads.
 209      *
 210      * @param i the index
 211      * @param updateFunction a side-effect-free function
 212      * @return the previous value
 213      * @since 1.8
 214      */
 215     public final E getAndUpdate(int i, UnaryOperator<E> updateFunction) {
 216         long offset = checkedByteOffset(i);
 217         E prev, next;
 218         do {
 219             prev = getRaw(offset);
 220             next = updateFunction.operate(prev);
 221         } while (!compareAndSetRaw(offset, prev, next));
 222         return prev;
 223     }
 224 
 225     /**
 226      * Atomically updates the element at index {@code i} with the results
 227      * of applying the given function. The function should be
 228      * side-effect-free, since it may be re-applied when attempted
 229      * updates fail due to contention among threads.
 230      *
 231      * @param i the index
 232      * @param updateFunction a side-effect-free function
 233      * @return the updated value
 234      * @since 1.8
 235      */
 236     public final E updateAndGet(int i, UnaryOperator<E> updateFunction) {
 237         long offset = checkedByteOffset(i);
 238         E prev, next;
 239         do {
 240             prev = getRaw(offset);
 241             next = updateFunction.operate(prev);
 242         } while (!compareAndSetRaw(offset, prev, next));
 243         return next;
 244     }
 245 
 246     /**
 247      * Atomically updates the element at index {@code i} with the results
 248      * of applying the given function to the current and given values.
 249      * The function should be side-effect-free, since it may be
 250      * re-applied when attempted updates fail due to contention among
 251      * threads.  The function is applied with the current value at index
 252      * {@code i} as its first argument, and the given update as the second
 253      * argument.
 254      *
 255      * @param i the index
 256      * @param x the update value
 257      * @param accumulatorFunction a side-effect-free function of two arguments
 258      * @return the previous value
 259      * @since 1.8
 260      */
 261     public final E getAndAccumulate(int i, E x,
 262                                     BinaryOperator<E> accumulatorFunction) {
 263         long offset = checkedByteOffset(i);
 264         E prev, next;
 265         do {
 266             prev = getRaw(offset);
 267             next = accumulatorFunction.operate(prev, x);
 268         } while (!compareAndSetRaw(offset, prev, next));
 269         return prev;
 270     }
 271 
 272     /**
 273      * Atomically updates the element at index {@code i} with the results
 274      * of applying the given function to the current and given values.
 275      * The function should be side-effect-free, since it may be
 276      * re-applied when attempted updates fail due to contention among
 277      * threads.  The function is applied with the current value at index
 278      * {@code i} as its first argument, and the given update as the second
 279      * argument.
 280      *
 281      * @param i the index
 282      * @param x the update value
 283      * @param accumulatorFunction a side-effect-free function of two arguments
 284      * @return the updated value
 285      * @since 1.8
 286      */
 287     public final E accumulateAndGet(int i, E x,
 288                                     BinaryOperator<E> accumulatorFunction) {
 289         long offset = checkedByteOffset(i);
 290         E prev, next;
 291         do {
 292             prev = getRaw(offset);
 293             next = accumulatorFunction.operate(prev, x);
 294         } while (!compareAndSetRaw(offset, prev, next));
 295         return next;
 296     }
 297 
 298     /**
 299      * Returns the String representation of the current values of array.
 300      * @return the String representation of the current values of array
 301      */
 302     public String toString() {
 303         int iMax = array.length - 1;
 304         if (iMax == -1)
 305             return "[]";
 306 
 307         StringBuilder b = new StringBuilder();
 308         b.append('[');
 309         for (int i = 0; ; i++) {
 310             b.append(getRaw(byteOffset(i)));
 311             if (i == iMax)
 312                 return b.append(']').toString();
 313             b.append(',').append(' ');
 314         }
 315     }
 316 
 317     /**