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