jdk/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java
changeset 41131 87edc8451f8a
parent 32838 caeef2c79243
child 45935 75c0f4d0ebea
equal deleted inserted replaced
41130:2004bf22423f 41131:87edc8451f8a
    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 static java.lang.Double.doubleToRawLongBits;
       
    39 import static java.lang.Double.longBitsToDouble;
    37 
    40 
    38 import java.io.Serializable;
    41 import java.io.Serializable;
    39 import java.util.function.DoubleBinaryOperator;
    42 import java.util.function.DoubleBinaryOperator;
    40 
    43 
    41 /**
    44 /**
    89      * @param identity identity (initial value) for the accumulator function
    92      * @param identity identity (initial value) for the accumulator function
    90      */
    93      */
    91     public DoubleAccumulator(DoubleBinaryOperator accumulatorFunction,
    94     public DoubleAccumulator(DoubleBinaryOperator accumulatorFunction,
    92                              double identity) {
    95                              double identity) {
    93         this.function = accumulatorFunction;
    96         this.function = accumulatorFunction;
    94         base = this.identity = Double.doubleToRawLongBits(identity);
    97         base = this.identity = doubleToRawLongBits(identity);
    95     }
    98     }
    96 
    99 
    97     /**
   100     /**
    98      * Updates with the given value.
   101      * Updates with the given value.
    99      *
   102      *
   100      * @param x the value
   103      * @param x the value
   101      */
   104      */
   102     public void accumulate(double x) {
   105     public void accumulate(double x) {
   103         Cell[] as; long b, v, r; int m; Cell a;
   106         Cell[] as; long b, v, r; int m; Cell a;
   104         if ((as = cells) != null ||
   107         if ((as = cells) != null
   105             (r = Double.doubleToRawLongBits
   108             || ((r = doubleToRawLongBits
   106              (function.applyAsDouble
   109                 (function.applyAsDouble(longBitsToDouble(b = base), x))) != b
   107               (Double.longBitsToDouble(b = base), x))) != b  && !casBase(b, r)) {
   110                 && !casBase(b, r))) {
   108             boolean uncontended = true;
   111             boolean uncontended = true;
   109             if (as == null || (m = as.length - 1) < 0 ||
   112             if (as == null
   110                 (a = as[getProbe() & m]) == null ||
   113                 || (m = as.length - 1) < 0
   111                 !(uncontended =
   114                 || (a = as[getProbe() & m]) == null
   112                   (r = Double.doubleToRawLongBits
   115                 || !(uncontended =
   113                    (function.applyAsDouble
   116                      ((r = doubleToRawLongBits
   114                     (Double.longBitsToDouble(v = a.value), x))) == v ||
   117                        (function.applyAsDouble
   115                   a.cas(v, r)))
   118                         (longBitsToDouble(v = a.value), x))) == v)
       
   119                      || a.cas(v, r)))
   116                 doubleAccumulate(x, function, uncontended);
   120                 doubleAccumulate(x, function, uncontended);
   117         }
   121         }
   118     }
   122     }
   119 
   123 
   120     /**
   124     /**
   126      *
   130      *
   127      * @return the current value
   131      * @return the current value
   128      */
   132      */
   129     public double get() {
   133     public double get() {
   130         Cell[] as = cells;
   134         Cell[] as = cells;
   131         double result = Double.longBitsToDouble(base);
   135         double result = longBitsToDouble(base);
   132         if (as != null) {
   136         if (as != null) {
   133             for (Cell a : as)
   137             for (Cell a : as)
   134                 if (a != null)
   138                 if (a != null)
   135                     result = function.applyAsDouble
   139                     result = function.applyAsDouble
   136                         (result, Double.longBitsToDouble(a.value));
   140                         (result, longBitsToDouble(a.value));
   137         }
   141         }
   138         return result;
   142         return result;
   139     }
   143     }
   140 
   144 
   141     /**
   145     /**
   166      *
   170      *
   167      * @return the value before reset
   171      * @return the value before reset
   168      */
   172      */
   169     public double getThenReset() {
   173     public double getThenReset() {
   170         Cell[] as = cells;
   174         Cell[] as = cells;
   171         double result = Double.longBitsToDouble(base);
   175         double result = longBitsToDouble(base);
   172         base = identity;
   176         base = identity;
   173         if (as != null) {
   177         if (as != null) {
   174             for (Cell a : as) {
   178             for (Cell a : as) {
   175                 if (a != null) {
   179                 if (a != null) {
   176                     double v = Double.longBitsToDouble(a.value);
   180                     double v = longBitsToDouble(a.value);
   177                     a.reset(identity);
   181                     a.reset(identity);
   178                     result = function.applyAsDouble(result, v);
   182                     result = function.applyAsDouble(result, v);
   179                 }
   183                 }
   180             }
   184             }
   181         }
   185         }
   265          *
   269          *
   266          * @return a {@code DoubleAccumulator} object with initial state
   270          * @return a {@code DoubleAccumulator} object with initial state
   267          * held by this proxy
   271          * held by this proxy
   268          */
   272          */
   269         private Object readResolve() {
   273         private Object readResolve() {
   270             double d = Double.longBitsToDouble(identity);
   274             double d = longBitsToDouble(identity);
   271             DoubleAccumulator a = new DoubleAccumulator(function, d);
   275             DoubleAccumulator a = new DoubleAccumulator(function, d);
   272             a.base = Double.doubleToRawLongBits(value);
   276             a.base = doubleToRawLongBits(value);
   273             return a;
   277             return a;
   274         }
   278         }
   275     }
   279     }
   276 
   280 
   277     /**
   281     /**