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 import java.io.Serializable; 38 39 /** 40 * One or more variables that together maintain an initially zero 41 * {@code double} sum. When updates (method {@link #add}) are 42 * contended across threads, the set of variables may grow dynamically 43 * to reduce contention. Method {@link #sum} (or, equivalently {@link 44 * #doubleValue}) returns the current total combined across the 45 * variables maintaining the sum. The order of accumulation within or 46 * across threads is not guaranteed. Thus, this class may not be 47 * applicable if numerical stability is required, especially when 48 * combining values of substantially different orders of magnitude. 49 * 50 * <p>This class is usually preferable to alternatives when multiple 51 * threads update a common value that is used for purposes such as 52 * summary statistics that are frequently updated but less frequently 53 * read. 54 * 55 * <p>This class extends {@link Number}, but does <em>not</em> define 56 * methods such as {@code equals}, {@code hashCode} and {@code 57 * compareTo} because instances are expected to be mutated, and so are 58 * not useful as collection keys. 59 * 60 * @since 1.8 61 * @author Doug Lea 62 */ 63 public class DoubleAdder extends Striped64 implements Serializable { 64 private static final long serialVersionUID = 7249069246863182397L; 65 66 /* 67 * Note that we must use "long" for underlying representations, 68 * because there is no compareAndSet for double, due to the fact 69 * that the bitwise equals used in any CAS implementation is not 70 * the same as double-precision equals. However, we use CAS only 71 * to detect and alleviate contention, for which bitwise equals 72 * works best anyway. In principle, the long/double conversions 73 * used here should be essentially free on most platforms since 74 * they just re-interpret bits. 75 */ 76 77 /** 78 * Creates a new adder with initial sum of zero. 79 */ DoubleAdder()80 public DoubleAdder() { 81 } 82 83 /** 84 * Adds the given value. 85 * 86 * @param x the value to add 87 */ add(double x)88 public void add(double x) { 89 Cell[] as; long b, v; int m; Cell a; 90 if ((as = cells) != null || 91 !casBase(b = base, 92 Double.doubleToRawLongBits 93 (Double.longBitsToDouble(b) + x))) { 94 boolean uncontended = true; 95 if (as == null || (m = as.length - 1) < 0 || 96 (a = as[getProbe() & m]) == null || 97 !(uncontended = a.cas(v = a.value, 98 Double.doubleToRawLongBits 99 (Double.longBitsToDouble(v) + x)))) 100 doubleAccumulate(x, null, uncontended); 101 } 102 } 103 104 /** 105 * Returns the current sum. The returned value is <em>NOT</em> an 106 * atomic snapshot; invocation in the absence of concurrent 107 * updates returns an accurate result, but concurrent updates that 108 * occur while the sum is being calculated might not be 109 * incorporated. Also, because floating-point arithmetic is not 110 * strictly associative, the returned result need not be identical 111 * to the value that would be obtained in a sequential series of 112 * updates to a single variable. 113 * 114 * @return the sum 115 */ sum()116 public double sum() { 117 Cell[] as = cells; Cell a; 118 double sum = Double.longBitsToDouble(base); 119 if (as != null) { 120 for (int i = 0; i < as.length; ++i) { 121 if ((a = as[i]) != null) 122 sum += Double.longBitsToDouble(a.value); 123 } 124 } 125 return sum; 126 } 127 128 /** 129 * Resets variables maintaining the sum to zero. This method may 130 * be a useful alternative to creating a new adder, but is only 131 * effective if there are no concurrent updates. Because this 132 * method is intrinsically racy, it should only be used when it is 133 * known that no threads are concurrently updating. 134 */ reset()135 public void reset() { 136 Cell[] as = cells; Cell a; 137 base = 0L; // relies on fact that double 0 must have same rep as long 138 if (as != null) { 139 for (int i = 0; i < as.length; ++i) { 140 if ((a = as[i]) != null) 141 a.value = 0L; 142 } 143 } 144 } 145 146 /** 147 * Equivalent in effect to {@link #sum} followed by {@link 148 * #reset}. This method may apply for example during quiescent 149 * points between multithreaded computations. If there are 150 * updates concurrent with this method, the returned value is 151 * <em>not</em> guaranteed to be the final value occurring before 152 * the reset. 153 * 154 * @return the sum 155 */ sumThenReset()156 public double sumThenReset() { 157 Cell[] as = cells; Cell a; 158 double sum = Double.longBitsToDouble(base); 159 base = 0L; 160 if (as != null) { 161 for (int i = 0; i < as.length; ++i) { 162 if ((a = as[i]) != null) { 163 long v = a.value; 164 a.value = 0L; 165 sum += Double.longBitsToDouble(v); 166 } 167 } 168 } 169 return sum; 170 } 171 172 /** 173 * Returns the String representation of the {@link #sum}. 174 * @return the String representation of the {@link #sum} 175 */ toString()176 public String toString() { 177 return Double.toString(sum()); 178 } 179 180 /** 181 * Equivalent to {@link #sum}. 182 * 183 * @return the sum 184 */ doubleValue()185 public double doubleValue() { 186 return sum(); 187 } 188 189 /** 190 * Returns the {@link #sum} as a {@code long} after a 191 * narrowing primitive conversion. 192 */ longValue()193 public long longValue() { 194 return (long)sum(); 195 } 196 197 /** 198 * Returns the {@link #sum} as an {@code int} after a 199 * narrowing primitive conversion. 200 */ intValue()201 public int intValue() { 202 return (int)sum(); 203 } 204 205 /** 206 * Returns the {@link #sum} as a {@code float} 207 * after a narrowing primitive conversion. 208 */ floatValue()209 public float floatValue() { 210 return (float)sum(); 211 } 212 213 /** 214 * Serialization proxy, used to avoid reference to the non-public 215 * Striped64 superclass in serialized forms. 216 * @serial include 217 */ 218 private static class SerializationProxy implements Serializable { 219 private static final long serialVersionUID = 7249069246863182397L; 220 221 /** 222 * The current value returned by sum(). 223 * @serial 224 */ 225 private final double value; 226 SerializationProxy(DoubleAdder a)227 SerializationProxy(DoubleAdder a) { 228 value = a.sum(); 229 } 230 231 /** 232 * Returns a {@code DoubleAdder} object with initial state 233 * held by this proxy. 234 * 235 * @return a {@code DoubleAdder} object with initial state 236 * held by this proxy. 237 */ readResolve()238 private Object readResolve() { 239 DoubleAdder a = new DoubleAdder(); 240 a.base = Double.doubleToRawLongBits(value); 241 return a; 242 } 243 } 244 245 /** 246 * Returns a 247 * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.DoubleAdder.SerializationProxy"> 248 * SerializationProxy</a> 249 * representing the state of this instance. 250 * 251 * @return a {@link SerializationProxy} 252 * representing the state of this instance 253 */ writeReplace()254 private Object writeReplace() { 255 return new SerializationProxy(this); 256 } 257 258 /** 259 * @param s the stream 260 * @throws java.io.InvalidObjectException always 261 */ readObject(java.io.ObjectInputStream s)262 private void readObject(java.io.ObjectInputStream s) 263 throws java.io.InvalidObjectException { 264 throw new java.io.InvalidObjectException("Proxy required"); 265 } 266 267 } 268