jdk/src/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
changeset 15020 50394fa17c1b
parent 14325 622c473a21aa
child 15267 c884f548a25f
equal deleted inserted replaced
15019:fb36233a54d9 15020:50394fa17c1b
    96      * necessarily with respect to other changes in the field.
    96      * necessarily with respect to other changes in the field.
    97      *
    97      *
    98      * @param obj An object whose field to conditionally set
    98      * @param obj An object whose field to conditionally set
    99      * @param expect the expected value
    99      * @param expect the expected value
   100      * @param update the new value
   100      * @param update the new value
   101      * @return true if successful.
   101      * @return true if successful
   102      * @throws ClassCastException if {@code obj} is not an instance
   102      * @throws ClassCastException if {@code obj} is not an instance
   103      * of the class possessing the field established in the constructor.
   103      * of the class possessing the field established in the constructor.
   104      */
   104      */
   105     public abstract boolean compareAndSet(T obj, long expect, long update);
   105     public abstract boolean compareAndSet(T obj, long expect, long update);
   106 
   106 
   116      * appropriate alternative to {@code compareAndSet}.
   116      * appropriate alternative to {@code compareAndSet}.
   117      *
   117      *
   118      * @param obj An object whose field to conditionally set
   118      * @param obj An object whose field to conditionally set
   119      * @param expect the expected value
   119      * @param expect the expected value
   120      * @param update the new value
   120      * @param update the new value
   121      * @return true if successful.
   121      * @return true if successful
   122      * @throws ClassCastException if {@code obj} is not an instance
   122      * @throws ClassCastException if {@code obj} is not an instance
   123      * of the class possessing the field established in the constructor.
   123      * of the class possessing the field established in the constructor.
   124      */
   124      */
   125     public abstract boolean weakCompareAndSet(T obj, long expect, long update);
   125     public abstract boolean weakCompareAndSet(T obj, long expect, long update);
   126 
   126 
   160      * @param obj An object whose field to get and set
   160      * @param obj An object whose field to get and set
   161      * @param newValue the new value
   161      * @param newValue the new value
   162      * @return the previous value
   162      * @return the previous value
   163      */
   163      */
   164     public long getAndSet(T obj, long newValue) {
   164     public long getAndSet(T obj, long newValue) {
   165         for (;;) {
   165         long prev;
   166             long current = get(obj);
   166         do {
   167             if (compareAndSet(obj, current, newValue))
   167             prev = get(obj);
   168                 return current;
   168         } while (!compareAndSet(obj, prev, newValue));
   169         }
   169         return prev;
   170     }
   170     }
   171 
   171 
   172     /**
   172     /**
   173      * Atomically increments by one the current value of the field of the
   173      * Atomically increments by one the current value of the field of the
   174      * given object managed by this updater.
   174      * given object managed by this updater.
   175      *
   175      *
   176      * @param obj An object whose field to get and set
   176      * @param obj An object whose field to get and set
   177      * @return the previous value
   177      * @return the previous value
   178      */
   178      */
   179     public long getAndIncrement(T obj) {
   179     public long getAndIncrement(T obj) {
   180         for (;;) {
   180         long prev, next;
   181             long current = get(obj);
   181         do {
   182             long next = current + 1;
   182             prev = get(obj);
   183             if (compareAndSet(obj, current, next))
   183             next = prev + 1;
   184                 return current;
   184         } while (!compareAndSet(obj, prev, next));
   185         }
   185         return prev;
   186     }
   186     }
   187 
   187 
   188     /**
   188     /**
   189      * Atomically decrements by one the current value of the field of the
   189      * Atomically decrements by one the current value of the field of the
   190      * given object managed by this updater.
   190      * given object managed by this updater.
   191      *
   191      *
   192      * @param obj An object whose field to get and set
   192      * @param obj An object whose field to get and set
   193      * @return the previous value
   193      * @return the previous value
   194      */
   194      */
   195     public long getAndDecrement(T obj) {
   195     public long getAndDecrement(T obj) {
   196         for (;;) {
   196         long prev, next;
   197             long current = get(obj);
   197         do {
   198             long next = current - 1;
   198             prev = get(obj);
   199             if (compareAndSet(obj, current, next))
   199             next = prev - 1;
   200                 return current;
   200         } while (!compareAndSet(obj, prev, next));
   201         }
   201         return prev;
   202     }
   202     }
   203 
   203 
   204     /**
   204     /**
   205      * Atomically adds the given value to the current value of the field of
   205      * Atomically adds the given value to the current value of the field of
   206      * the given object managed by this updater.
   206      * the given object managed by this updater.
   208      * @param obj An object whose field to get and set
   208      * @param obj An object whose field to get and set
   209      * @param delta the value to add
   209      * @param delta the value to add
   210      * @return the previous value
   210      * @return the previous value
   211      */
   211      */
   212     public long getAndAdd(T obj, long delta) {
   212     public long getAndAdd(T obj, long delta) {
   213         for (;;) {
   213         long prev, next;
   214             long current = get(obj);
   214         do {
   215             long next = current + delta;
   215             prev = get(obj);
   216             if (compareAndSet(obj, current, next))
   216             next = prev + delta;
   217                 return current;
   217         } while (!compareAndSet(obj, prev, next));
   218         }
   218         return prev;
   219     }
   219     }
   220 
   220 
   221     /**
   221     /**
   222      * Atomically increments by one the current value of the field of the
   222      * Atomically increments by one the current value of the field of the
   223      * given object managed by this updater.
   223      * given object managed by this updater.
   224      *
   224      *
   225      * @param obj An object whose field to get and set
   225      * @param obj An object whose field to get and set
   226      * @return the updated value
   226      * @return the updated value
   227      */
   227      */
   228     public long incrementAndGet(T obj) {
   228     public long incrementAndGet(T obj) {
   229         for (;;) {
   229         long prev, next;
   230             long current = get(obj);
   230         do {
   231             long next = current + 1;
   231             prev = get(obj);
   232             if (compareAndSet(obj, current, next))
   232             next = prev + 1;
   233                 return next;
   233         } while (!compareAndSet(obj, prev, next));
   234         }
   234         return next;
   235     }
   235     }
   236 
   236 
   237     /**
   237     /**
   238      * Atomically decrements by one the current value of the field of the
   238      * Atomically decrements by one the current value of the field of the
   239      * given object managed by this updater.
   239      * given object managed by this updater.
   240      *
   240      *
   241      * @param obj An object whose field to get and set
   241      * @param obj An object whose field to get and set
   242      * @return the updated value
   242      * @return the updated value
   243      */
   243      */
   244     public long decrementAndGet(T obj) {
   244     public long decrementAndGet(T obj) {
   245         for (;;) {
   245         long prev, next;
   246             long current = get(obj);
   246         do {
   247             long next = current - 1;
   247             prev = get(obj);
   248             if (compareAndSet(obj, current, next))
   248             next = prev - 1;
   249                 return next;
   249         } while (!compareAndSet(obj, prev, next));
   250         }
   250         return next;
   251     }
   251     }
   252 
   252 
   253     /**
   253     /**
   254      * Atomically adds the given value to the current value of the field of
   254      * Atomically adds the given value to the current value of the field of
   255      * the given object managed by this updater.
   255      * the given object managed by this updater.
   257      * @param obj An object whose field to get and set
   257      * @param obj An object whose field to get and set
   258      * @param delta the value to add
   258      * @param delta the value to add
   259      * @return the updated value
   259      * @return the updated value
   260      */
   260      */
   261     public long addAndGet(T obj, long delta) {
   261     public long addAndGet(T obj, long delta) {
   262         for (;;) {
   262         long prev, next;
   263             long current = get(obj);
   263         do {
   264             long next = current + delta;
   264             prev = get(obj);
   265             if (compareAndSet(obj, current, next))
   265             next = prev + delta;
   266                 return next;
   266         } while (!compareAndSet(obj, prev, next));
   267         }
   267         return next;
   268     }
   268     }
   269 
   269 
   270     private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
   270     private static class CASUpdater<T> extends AtomicLongFieldUpdater<T> {
   271         private static final Unsafe unsafe = Unsafe.getUnsafe();
   271         private static final Unsafe unsafe = Unsafe.getUnsafe();
   272         private final long offset;
   272         private final long offset;
   343         public long get(T obj) {
   343         public long get(T obj) {
   344             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
   344             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
   345             return unsafe.getLongVolatile(obj, offset);
   345             return unsafe.getLongVolatile(obj, offset);
   346         }
   346         }
   347 
   347 
       
   348         public long getAndSet(T obj, long newValue) {
       
   349             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
       
   350             return unsafe.getAndSetLong(obj, offset, newValue);
       
   351         }
       
   352 
       
   353         public long getAndIncrement(T obj) {
       
   354             return getAndAdd(obj, 1);
       
   355         }
       
   356 
       
   357         public long getAndDecrement(T obj) {
       
   358             return getAndAdd(obj, -1);
       
   359         }
       
   360 
       
   361         public long getAndAdd(T obj, long delta) {
       
   362             if (obj == null || obj.getClass() != tclass || cclass != null) fullCheck(obj);
       
   363             return unsafe.getAndAddLong(obj, offset, delta);
       
   364         }
       
   365 
       
   366         public long incrementAndGet(T obj) {
       
   367             return getAndAdd(obj, 1) + 1;
       
   368         }
       
   369 
       
   370         public long decrementAndGet(T obj) {
       
   371              return getAndAdd(obj, -1) - 1;
       
   372         }
       
   373 
       
   374         public long addAndGet(T obj, long delta) {
       
   375             return getAndAdd(obj, delta) + delta;
       
   376         }
       
   377 
   348         private void ensureProtectedAccess(T obj) {
   378         private void ensureProtectedAccess(T obj) {
   349             if (cclass.isInstance(obj)) {
   379             if (cclass.isInstance(obj)) {
   350                 return;
   380                 return;
   351             }
   381             }
   352             throw new RuntimeException(
   382             throw new RuntimeException(