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 @SuppressWarnings("serial") // Not statically typed as Serializable 88 private final DoubleBinaryOperator function; 89 private final long identity; // use long representation 90 91 /** 92 * Creates a new instance using the given accumulator function 93 * and identity element. 94 * @param accumulatorFunction a side-effect-free function of two arguments 95 * @param identity identity (initial value) for the accumulator function 96 */ DoubleAccumulator(DoubleBinaryOperator accumulatorFunction, double identity)97 public DoubleAccumulator(DoubleBinaryOperator accumulatorFunction, 98 double identity) { 99 this.function = accumulatorFunction; 100 base = this.identity = doubleToRawLongBits(identity); 101 } 102 103 /** 104 * Updates with the given value. 105 * 106 * @param x the value 107 */ accumulate(double x)108 public void accumulate(double x) { 109 Cell[] cs; long b, v, r; int m; Cell c; 110 if ((cs = cells) != null 111 || ((r = doubleToRawLongBits 112 (function.applyAsDouble(longBitsToDouble(b = base), x))) != b 113 && !casBase(b, r))) { 114 int index = getProbe(); 115 boolean uncontended = true; 116 if (cs == null 117 || (m = cs.length - 1) < 0 118 || (c = cs[index & m]) == null 119 || !(uncontended = 120 ((r = doubleToRawLongBits 121 (function.applyAsDouble 122 (longBitsToDouble(v = c.value), x))) == v) 123 || c.cas(v, r))) 124 doubleAccumulate(x, function, uncontended, index); 125 } 126 } 127 128 /** 129 * Returns the current value. The returned value is <em>NOT</em> 130 * an atomic snapshot; invocation in the absence of concurrent 131 * updates returns an accurate result, but concurrent updates that 132 * occur while the value is being calculated might not be 133 * incorporated. 134 * 135 * @return the current value 136 */ get()137 public double get() { 138 Cell[] cs = cells; 139 double result = longBitsToDouble(base); 140 if (cs != null) { 141 for (Cell c : cs) 142 if (c != null) 143 result = function.applyAsDouble 144 (result, longBitsToDouble(c.value)); 145 } 146 return result; 147 } 148 149 /** 150 * Resets variables maintaining updates to the identity value. 151 * This method may be a useful alternative to creating a new 152 * updater, but is only effective if there are no concurrent 153 * updates. Because this method is intrinsically racy, it should 154 * only be used when it is known that no threads are concurrently 155 * updating. 156 */ reset()157 public void reset() { 158 Cell[] cs = cells; 159 base = identity; 160 if (cs != null) { 161 for (Cell c : cs) 162 if (c != null) 163 c.reset(identity); 164 } 165 } 166 167 /** 168 * Equivalent in effect to {@link #get} followed by {@link 169 * #reset}. This method may apply for example during quiescent 170 * points between multithreaded computations. If there are 171 * updates concurrent with this method, the returned value is 172 * <em>not</em> guaranteed to be the final value occurring before 173 * the reset. 174 * 175 * @return the value before reset 176 */ getThenReset()177 public double getThenReset() { 178 Cell[] cs = cells; 179 double result = longBitsToDouble(getAndSetBase(identity)); 180 if (cs != null) { 181 for (Cell c : cs) { 182 if (c != null) { 183 double v = longBitsToDouble(c.getAndSet(identity)); 184 result = function.applyAsDouble(result, v); 185 } 186 } 187 } 188 return result; 189 } 190 191 /** 192 * Returns the String representation of the current value. 193 * @return the String representation of the current value 194 */ toString()195 public String toString() { 196 return Double.toString(get()); 197 } 198 199 /** 200 * Equivalent to {@link #get}. 201 * 202 * @return the current value 203 */ doubleValue()204 public double doubleValue() { 205 return get(); 206 } 207 208 /** 209 * Returns the {@linkplain #get current value} as a {@code long} 210 * after a narrowing primitive conversion. 211 */ longValue()212 public long longValue() { 213 return (long)get(); 214 } 215 216 /** 217 * Returns the {@linkplain #get current value} as an {@code int} 218 * after a narrowing primitive conversion. 219 */ intValue()220 public int intValue() { 221 return (int)get(); 222 } 223 224 /** 225 * Returns the {@linkplain #get current value} as a {@code float} 226 * after a narrowing primitive conversion. 227 */ floatValue()228 public float floatValue() { 229 return (float)get(); 230 } 231 232 /** 233 * Serialization proxy, used to avoid reference to the non-public 234 * Striped64 superclass in serialized forms. 235 * @serial include 236 */ 237 private static class SerializationProxy implements Serializable { 238 private static final long serialVersionUID = 7249069246863182397L; 239 240 /** 241 * The current value returned by get(). 242 * @serial 243 */ 244 private final double value; 245 246 /** 247 * The function used for updates. 248 * @serial 249 */ 250 @SuppressWarnings("serial") // Not statically typed as Serializable 251 private final DoubleBinaryOperator function; 252 253 /** 254 * The identity value, represented as a long, as converted by 255 * {@link Double#doubleToRawLongBits}. The original identity 256 * can be recovered using {@link Double#longBitsToDouble}. 257 * @serial 258 */ 259 private final long identity; 260 SerializationProxy(double value, DoubleBinaryOperator function, long identity)261 SerializationProxy(double value, 262 DoubleBinaryOperator function, 263 long identity) { 264 this.value = value; 265 this.function = function; 266 this.identity = identity; 267 } 268 269 /** 270 * Returns a {@code DoubleAccumulator} object with initial state 271 * held by this proxy. 272 * 273 * @return a {@code DoubleAccumulator} object with initial state 274 * held by this proxy 275 */ readResolve()276 private Object readResolve() { 277 double d = longBitsToDouble(identity); 278 DoubleAccumulator a = new DoubleAccumulator(function, d); 279 a.base = doubleToRawLongBits(value); 280 return a; 281 } 282 } 283 284 /** 285 * Returns a 286 * <a href="{@docRoot}/serialized-form.html#java.util.concurrent.atomic.DoubleAccumulator.SerializationProxy"> 287 * SerializationProxy</a> 288 * representing the state of this instance. 289 * 290 * @return a {@link SerializationProxy} 291 * representing the state of this instance 292 */ writeReplace()293 private Object writeReplace() { 294 return new SerializationProxy(get(), function, identity); 295 } 296 297 /** 298 * @param s the stream 299 * @throws java.io.InvalidObjectException always 300 */ readObject(java.io.ObjectInputStream s)301 private void readObject(java.io.ObjectInputStream s) 302 throws java.io.InvalidObjectException { 303 throw new java.io.InvalidObjectException("Proxy required"); 304 } 305 306 } 307