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 long} sum. When updates (method {@link #add}) are contended 43 * across threads, the set of variables may grow dynamically to reduce 44 * contention. Method {@link #sum} (or, equivalently, {@link 45 * #longValue}) returns the current total combined across the 46 * variables maintaining the sum. 47 * 48 * <p>This class is usually preferable to {@link AtomicLong} when 49 * multiple threads update a common sum that is used for purposes such 50 * as collecting statistics, not for fine-grained synchronization 51 * control. Under low update contention, the two classes have similar 52 * characteristics. But under high contention, expected throughput of 53 * this class is significantly higher, at the expense of higher space 54 * consumption. 55 * 56 * <p>LongAdders can be used with a {@link 57 * java.util.concurrent.ConcurrentHashMap} to maintain a scalable 58 * frequency map (a form of histogram or multiset). For example, to 59 * add a count to a {@code ConcurrentHashMap<String,LongAdder> freqs}, 60 * initializing if not already present, you can use {@code 61 * freqs.computeIfAbsent(key, k -> new LongAdder()).increment();} 62 * 63 * <p>This class extends {@link Number}, but does <em>not</em> define 64 * methods such as {@code equals}, {@code hashCode} and {@code 65 * compareTo} because instances are expected to be mutated, and so are 66 * not useful as collection keys. 67 * 68 * @since 1.8 69 * @author Doug Lea 70 */ 71 public class LongAdder extends Striped64 implements Serializable { 72 private static final long serialVersionUID = 7249069246863182397L; 73 74 /** 75 * Creates a new adder with initial sum of zero. 76 */ 77 public LongAdder() { 78 } 79 80 /** 81 * Adds the given value. 82 * 83 * @param x the value to add 84 */ 85 public void add(long x) { 86 Cell[] cs; long b, v; int m; Cell c; 87 if ((cs = cells) != null || !casBase(b = base, b + x)) { 88 boolean uncontended = true; 89 if (cs == null || (m = cs.length - 1) < 0 || 90 (c = cs[getProbe() & m]) == null || 91 !(uncontended = c.cas(v = c.value, v + x))) 92 longAccumulate(x, null, uncontended); 93 } 94 } 95 96 /** 97 * Equivalent to {@code add(1)}. 98 */ 99 public void increment() { 100 add(1L); 101 } 102 103 /** 104 * Equivalent to {@code add(-1)}. 105 */ 106 public void decrement() { 107 add(-1L); 108 } 109 110 /** 111 * Returns the current sum. The returned value is <em>NOT</em> an 112 * atomic snapshot; invocation in the absence of concurrent 113 * updates returns an accurate result, but concurrent updates that 114 * occur while the sum is being calculated might not be 115 * incorporated. 116 * 117 * @return the sum 118 */ 119 public long sum() { 120 Cell[] cs = cells; 121 long sum = base; 122 if (cs != null) { 123 for (Cell c : cs) 124 if (c != null) 125 sum += c.value; 126 } 127 return sum; 128 } 129 130 /** 131 * Resets variables maintaining the sum to zero. This method may 132 * be a useful alternative to creating a new adder, but is only 133 * effective if there are no concurrent updates. Because this 134 * method is intrinsically racy, it should only be used when it is 135 * known that no threads are concurrently updating. 136 */ 137 public void reset() { 138 Cell[] cs = cells; 139 base = 0L; 140 if (cs != null) { 141 for (Cell c : cs) 142 if (c != null) 143 c.reset(); 144 } 145 } 146 147 /** 148 * Equivalent in effect to {@link #sum} followed by {@link 149 * #reset}. This method may apply for example during quiescent 150 * points between multithreaded computations. If there are 151 * updates concurrent with this method, the returned value is 152 * <em>not</em> guaranteed to be the final value occurring before 153 * the reset. 154 * 155 * @return the sum 156 */ 157 public long sumThenReset() { 158 Cell[] cs = cells; 159 long sum = getAndSetBase(0L); 160 if (cs != null) { 161 for (Cell c : cs) { 162 if (c != null) 163 sum += c.getAndSet(0L); 164 } 165 } 166 return sum; 167 } 168 169 /** 170 * Returns the String representation of the {@link #sum}. 171 * @return the String representation of the {@link #sum} 172 */ 173 public String toString() { 174 return Long.toString(sum()); 175 } 176 177 /** 178 * Equivalent to {@link #sum}. 179 * 180 * @return the sum 181 */ 182 public long longValue() { 183 return sum(); 184 } 185 186 /** 187 * Returns the {@link #sum} as an {@code int} after a narrowing 188 * primitive conversion. 189 */ 190 public int intValue() { 191 return (int)sum(); 192 } 193 194 /** 195 * Returns the {@link #sum} as a {@code float} 196 * after a widening primitive conversion. 197 */ 198 public float floatValue() { 199 return (float)sum(); 200 } 201 202 /** 203 * Returns the {@link #sum} as a {@code double} after a widening 204 * primitive conversion. 205 */ 206 public double doubleValue() { 207 return (double)sum(); 208 } 209 210 /** 211 * Serialization proxy, used to avoid reference to the non-public 212 * Striped64 superclass in serialized forms. 213 * @serial include 214 */ 215 private static class SerializationProxy implements Serializable { 216 private static final long serialVersionUID = 7249069246863182397L; 217 218 /** 219 * The current value returned by sum(). 220 * @serial 221 */ 222 private final long value; 223 224 SerializationProxy(LongAdder a) { 225 value = a.sum(); 226 } 227 228 /** 229 * Returns a {@code LongAdder} object with initial state 230 * held by this proxy. 231 * 232 * @return a {@code LongAdder} object with initial state 233 * held by this proxy 234 */ 235 private Object readResolve() { 236 LongAdder a = new LongAdder(); 237 a.base = value; 238 return a; 239 } 240 } 241 242 /** 243 * Returns a 244 * <a href="../../../../serialized-form.html#java.util.concurrent.atomic.LongAdder.SerializationProxy"> 245 * SerializationProxy</a> 246 * representing the state of this instance. 247 * 248 * @return a {@link SerializationProxy} 249 * representing the state of this instance 250 */ 251 private Object writeReplace() { 252 return new SerializationProxy(this); 253 } 254 255 /** 256 * @param s the stream 257 * @throws java.io.InvalidObjectException always 258 */ 259 private void readObject(java.io.ObjectInputStream s) 260 throws java.io.InvalidObjectException { 261 throw new java.io.InvalidObjectException("Proxy required"); 262 } 263 264 }