jdk/src/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java
changeset 18576 7a5c231327af
parent 16011 890a7ed97f6c
equal deleted inserted replaced
18575:2ab0d0b3ecad 18576:7a5c231327af
    32  * Expert Group and released to the public domain, as explained at
    32  * Expert Group and released to the public domain, as explained at
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    34  */
    34  */
    35 
    35 
    36 package java.util.concurrent.atomic;
    36 package java.util.concurrent.atomic;
    37 
       
    38 import java.util.Arrays;
       
    39 import java.util.function.UnaryOperator;
    37 import java.util.function.UnaryOperator;
    40 import java.util.function.BinaryOperator;
    38 import java.util.function.BinaryOperator;
       
    39 import java.util.Arrays;
    41 import java.lang.reflect.Array;
    40 import java.lang.reflect.Array;
    42 import sun.misc.Unsafe;
    41 import sun.misc.Unsafe;
    43 
    42 
    44 /**
    43 /**
    45  * An array of object references in which elements may be updated
    44  * An array of object references in which elements may be updated
    58     private static final int shift;
    57     private static final int shift;
    59     private static final long arrayFieldOffset;
    58     private static final long arrayFieldOffset;
    60     private final Object[] array; // must have exact type Object[]
    59     private final Object[] array; // must have exact type Object[]
    61 
    60 
    62     static {
    61     static {
    63         int scale;
       
    64         try {
    62         try {
    65             unsafe = Unsafe.getUnsafe();
    63             unsafe = Unsafe.getUnsafe();
    66             arrayFieldOffset = unsafe.objectFieldOffset
    64             arrayFieldOffset = unsafe.objectFieldOffset
    67                 (AtomicReferenceArray.class.getDeclaredField("array"));
    65                 (AtomicReferenceArray.class.getDeclaredField("array"));
    68             base = unsafe.arrayBaseOffset(Object[].class);
    66             base = unsafe.arrayBaseOffset(Object[].class);
    69             scale = unsafe.arrayIndexScale(Object[].class);
    67             int scale = unsafe.arrayIndexScale(Object[].class);
       
    68             if ((scale & (scale - 1)) != 0)
       
    69                 throw new Error("data type scale not a power of two");
       
    70             shift = 31 - Integer.numberOfLeadingZeros(scale);
    70         } catch (Exception e) {
    71         } catch (Exception e) {
    71             throw new Error(e);
    72             throw new Error(e);
    72         }
    73         }
    73         if ((scale & (scale - 1)) != 0)
       
    74             throw new Error("data type scale not a power of two");
       
    75         shift = 31 - Integer.numberOfLeadingZeros(scale);
       
    76     }
    74     }
    77 
    75 
    78     private long checkedByteOffset(int i) {
    76     private long checkedByteOffset(int i) {
    79         if (i < 0 || i >= array.length)
    77         if (i < 0 || i >= array.length)
    80             throw new IndexOutOfBoundsException("index " + i);
    78             throw new IndexOutOfBoundsException("index " + i);
   171      * updated value if the current value {@code ==} the expected value.
   169      * updated value if the current value {@code ==} the expected value.
   172      *
   170      *
   173      * @param i the index
   171      * @param i the index
   174      * @param expect the expected value
   172      * @param expect the expected value
   175      * @param update the new value
   173      * @param update the new value
   176      * @return true if successful. False return indicates that
   174      * @return {@code true} if successful. False return indicates that
   177      * the actual value was not equal to the expected value.
   175      * the actual value was not equal to the expected value.
   178      */
   176      */
   179     public final boolean compareAndSet(int i, E expect, E update) {
   177     public final boolean compareAndSet(int i, E expect, E update) {
   180         return compareAndSetRaw(checkedByteOffset(i), expect, update);
   178         return compareAndSetRaw(checkedByteOffset(i), expect, update);
   181     }
   179     }
   186 
   184 
   187     /**
   185     /**
   188      * Atomically sets the element at position {@code i} to the given
   186      * Atomically sets the element at position {@code i} to the given
   189      * updated value if the current value {@code ==} the expected value.
   187      * updated value if the current value {@code ==} the expected value.
   190      *
   188      *
   191      * <p>May <a href="package-summary.html#Spurious">fail spuriously</a>
   189      * <p><a href="package-summary.html#weakCompareAndSet">May fail
   192      * and does not provide ordering guarantees, so is only rarely an
   190      * spuriously and does not provide ordering guarantees</a>, so is
   193      * appropriate alternative to {@code compareAndSet}.
   191      * only rarely an appropriate alternative to {@code compareAndSet}.
   194      *
   192      *
   195      * @param i the index
   193      * @param i the index
   196      * @param expect the expected value
   194      * @param expect the expected value
   197      * @param update the new value
   195      * @param update the new value
   198      * @return true if successful
   196      * @return {@code true} if successful
   199      */
   197      */
   200     public final boolean weakCompareAndSet(int i, E expect, E update) {
   198     public final boolean weakCompareAndSet(int i, E expect, E update) {
   201         return compareAndSet(i, expect, update);
   199         return compareAndSet(i, expect, update);
   202     }
   200     }
   203 
   201 
   204       /**
   202     /**
   205      * Atomically updates the element at index {@code i} with the results
   203      * Atomically updates the element at index {@code i} with the results
   206      * of applying the given function, returning the previous value. The
   204      * of applying the given function, returning the previous value. The
   207      * function should be side-effect-free, since it may be re-applied
   205      * function should be side-effect-free, since it may be re-applied
   208      * when attempted updates fail due to contention among threads.
   206      * when attempted updates fail due to contention among threads.
   209      *
   207      *