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