1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 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 static java.lang.Double.doubleToRawLongBits; 39 import static java.lang.Double.longBitsToDouble; 40 41 import java.io.Serializable; 42 import java.util.function.DoubleBinaryOperator; 43 44 /** 45 * One or more variables that together maintain a running {@code double} 46 * value updated using a supplied function. When updates (method 47 * {@link #accumulate}) are contended across threads, the set of variables 48 * may grow dynamically to reduce contention. Method {@link #get} 49 * (or, equivalently, {@link #doubleValue}) returns the current value 50 * across the variables maintaining updates. 51 * 52 * <p>This class is usually preferable to alternatives when multiple 53 * threads update a common value that is used for purposes such as 54 * summary statistics that are frequently updated but less frequently 55 * read. 56 * 57 * <p>The supplied accumulator function should be side-effect-free, 58 * since it may be re-applied when attempted updates fail due to 59 * contention among threads. For predictable results, the accumulator 60 * function should be commutative and associative within the floating 61 * point tolerance required in usage contexts. The function is applied 62 * with an existing value (or identity) as one argument, and a given 63 * update as the other argument. For example, to maintain a running 64 * maximum value, you could supply {@code Double::max} along with 65 * {@code Double.NEGATIVE_INFINITY} as the identity. The order of 66 * accumulation within or across threads is not guaranteed. Thus, this 67 * class may not be applicable if numerical stability is required, 68 * especially when combining values of substantially different orders 69 * of magnitude. 70 * 71 * <p>Class {@link DoubleAdder} provides analogs of the functionality 72 * of this class for the common special case of maintaining sums. The 73 * call {@code new DoubleAdder()} is equivalent to {@code new 74 * DoubleAccumulator((x, y) -> x + y, 0.0)}. 75 * 76 * <p>This class extends {@link Number}, but does <em>not</em> define 77 * methods such as {@code equals}, {@code hashCode} and {@code 78 * compareTo} because instances are expected to be mutated, and so are 79 * not useful as collection keys. 80 * 81 * @since 1.8 82 * @author Doug Lea 83 */ 84 public class DoubleAccumulator extends Striped64 implements Serializable { 85 private static final long serialVersionUID = 7249069246863182397L; 86 87 private final DoubleBinaryOperator function; 88 private final long identity; // use long representation 89 90 /** 91 * Creates a new instance using the given accumulator function 92 * and identity element. 93 * @param accumulatorFunction a side-effect-free function of two arguments 94 * @param identity identity (initial value) for the accumulator function 95 */ DoubleAccumulator(DoubleBinaryOperator accumulatorFunction, double identity)96 public DoubleAccumulator(DoubleBinaryOperator accumulatorFunction, 97 double identity) { 98 this.function = accumulatorFunction; 99 base = this.identity = doubleToRawLongBits(identity); 100 } 101 102 /** 103 * Updates with the given value. 104 * 105 * @param x the value 106 */ accumulate(double x)107 public void accumulate(double x) { 108 Cell[] cs; long b, v, r; int m; Cell c; 109 if ((cs = cells) != null 110 || ((r = doubleToRawLongBits 111 (function.applyAsDouble(longBitsToDouble(b = base), x))) != b 112 && !casBase(b, r))) { 113 boolean uncontended = true; 114 if (cs == null 115 || (m = cs.length - 1) < 0 116 || (c = cs[getProbe() & m]) == null 117 || !(uncontended = 118 ((r = doubleToRawLongBits 119 (function.applyAsDouble 120 (longBitsToDouble(v = c.value), x))) == v) 121 || c.cas(v, r))) 122 doubleAccumulate(x, function, uncontended); 123 } 124 } 125 126 /** 127 * Returns the current value. The returned value is <em>NOT</em> 128 * an atomic snapshot; invocation in the absence of concurrent 129 * updates returns an accurate result, but concurrent updates that 130 * occur while the value is being calculated might not be 131 * incorporated. 132 * 133 * @return the current value 134 */ get()135 public double get() { 136 Cell[] cs = cells; 137 double result = longBitsToDouble(base); 138 if (cs != null) { 139 for (Cell c : cs) 140 if (c != null) 141 result = function.applyAsDouble 142 (result, longBitsToDouble(c.value)); 143 } 144 return result; 145 } 146 147 /** 148 * Resets variables maintaining updates to the identity value. 149 * This method may be a useful alternative to creating a new 150 * updater, but is only effective if there are no concurrent 151 * updates. Because this method is intrinsically racy, it should 152 * only be used when it is known that no threads are concurrently 153 * updating. 154 */ reset()155 public void reset() { 156 Cell[] cs = cells; 157 base = identity; 158 if (cs != null) { 159 for (Cell c : cs) 160 if (c != null) 161 c.reset(identity); 162 } 163 } 164 165 /** 166 * Equivalent in effect to {@link #get} followed by {@link 167 * #reset}. This method may apply for example during quiescent 168 * points between multithreaded computations. If there are 169 * updates concurrent with this method, the returned value is 170 * <em>not</em> guaranteed to be the final value occurring before 171 * the reset. 172 * 173 * @return the value before reset 174 */ getThenReset()175 public double getThenReset() { 176 Cell[] cs = cells; 177 double result = longBitsToDouble(getAndSetBase(identity)); 178 if (cs != null) { 179 for (Cell c : cs) { 180 if (c != null) { 181 double v = longBitsToDouble(c.getAndSet(identity)); 182 result = function.applyAsDouble(result, v); 183 } 184 } 185 } 186 return result; 187 } 188 189 /** 190 * Returns the String representation of the current value. 191 * @return the String representation of the current value 192 */ toString()193 public String toString() { 194 return Double.toString(get()); 195 } 196 197 /** 198 * Equivalent to {@link #get}. 199 * 200 * @return the current value 201 */ doubleValue()202 public double doubleValue() { 203 return get(); 204 } 205 206 /** 207 * Returns the {@linkplain #get current value} as a {@code long} 208 * after a narrowing primitive conversion. 209 */ longValue()210 public long longValue() { 211 return (long)get(); 212 } 213 214 /** 215 * Returns the {@linkplain #get current value} as an {@code int} 216 * after a narrowing primitive conversion. 217 */ intValue()218 public int intValue() { 219 return (int)get(); 220 } 221 222 /** 223 * Returns the {@linkplain #get current value} as a {@code float} 224 * after a narrowing primitive conversion. 225 */ floatValue()226 public float floatValue() { 227 return (float)get(); 228 } 229 230 /** 231 * Serialization proxy, used to avoid reference to the non-public 232 * Striped64 superclass in serialized forms. 233 * @serial include 234 */ 235 private static class SerializationProxy implements Serializable { 236 private static final long serialVersionUID = 7249069246863182397L; 237 238 /** 239 * The current value returned by get(). 240 * @serial 241 */ 242 private final double value; 243 244 /** 245 * The function used for updates. 246 * @serial 247 */ 248 private final DoubleBinaryOperator function; 249 250 /** 251 * The identity value, represented as a long, as converted by 252 * {@link Double#doubleToRawLongBits}. The original identity 253 * can be recovered using {@link Double#longBitsToDouble}. 254 * @serial 255 */ 256 private final long identity; 257 SerializationProxy(double value, DoubleBinaryOperator function, long identity)258 SerializationProxy(double value, 259 DoubleBinaryOperator function, 260 long identity) { 261 this.value = value; 262 this.function = function; 263 this.identity = identity; 264 } 265 266 /** 267 * Returns a {@code DoubleAccumulator} object with initial state 268 * held by this proxy. 269 * 270 * @return a {@code DoubleAccumulator} object with initial state 271 * held by this proxy 272 */ readResolve()273 private Object readResolve() { 274 double d = longBitsToDouble(identity); 275 DoubleAccumulator a = new DoubleAccumulator(function, d); 276 a.base = doubleToRawLongBits(value); 277 return a; 278 } 279 } 280 281 /** 282 * Returns a 283 * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.DoubleAccumulator.SerializationProxy"> 284 * SerializationProxy</a> 285 * representing the state of this instance. 286 * 287 * @return a {@link SerializationProxy} 288 * representing the state of this instance 289 */ writeReplace()290 private Object writeReplace() { 291 return new SerializationProxy(get(), function, identity); 292 } 293 294 /** 295 * @param s the stream 296 * @throws java.io.InvalidObjectException always 297 */ readObject(java.io.ObjectInputStream s)298 private void readObject(java.io.ObjectInputStream s) 299 throws java.io.InvalidObjectException { 300 throw new java.io.InvalidObjectException("Proxy required"); 301 } 302 303 } 304