ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdder.java
Revision: 1.17
Committed: Mon May 5 20:20:15 2014 UTC (9 years, 11 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.16: +8 -5 lines
Log Message:
import everything to reduce diffs with guava fork

File Contents

# Content
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 jsr166e;
8
9 import java.io.IOException;
10 import java.io.ObjectInputStream;
11 import java.io.ObjectOutputStream;
12 import java.io.Serializable;
13 import java.util.concurrent.atomic.AtomicLong;
14
15 /**
16 * One or more variables that together maintain an initially zero
17 * {@code long} sum. When updates (method {@link #add}) are contended
18 * across threads, the set of variables may grow dynamically to reduce
19 * contention. Method {@link #sum} (or, equivalently, {@link
20 * #longValue}) returns the current total combined across the
21 * variables maintaining the sum.
22 *
23 * <p>This class is usually preferable to {@link AtomicLong} when
24 * multiple threads update a common sum that is used for purposes such
25 * as collecting statistics, not for fine-grained synchronization
26 * control. Under low update contention, the two classes have similar
27 * characteristics. But under high contention, expected throughput of
28 * this class is significantly higher, at the expense of higher space
29 * consumption.
30 *
31 * <p>This class extends {@link Number}, but does <em>not</em> define
32 * methods such as {@code equals}, {@code hashCode} and {@code
33 * compareTo} because instances are expected to be mutated, and so are
34 * not useful as collection keys.
35 *
36 * <p><em>jsr166e note: This class is targeted to be placed in
37 * java.util.concurrent.atomic.</em>
38 *
39 * @since 1.8
40 * @author Doug Lea
41 */
42 public class LongAdder extends Striped64 implements Serializable {
43 private static final long serialVersionUID = 7249069246863182397L;
44
45 /**
46 * Version of plus for use in retryUpdate
47 */
48 final long fn(long v, long x) { return v + x; }
49
50 /**
51 * Creates a new adder with initial sum of zero.
52 */
53 public LongAdder() {
54 }
55
56 /**
57 * Adds the given value.
58 *
59 * @param x the value to add
60 */
61 public void add(long x) {
62 Cell[] as; long b, v; int[] hc; Cell a; int n;
63 if ((as = cells) != null || !casBase(b = base, b + x)) {
64 boolean uncontended = true;
65 if ((hc = threadHashCode.get()) == null ||
66 as == null || (n = as.length) < 1 ||
67 (a = as[(n - 1) & hc[0]]) == null ||
68 !(uncontended = a.cas(v = a.value, v + x)))
69 retryUpdate(x, hc, uncontended);
70 }
71 }
72
73 /**
74 * Equivalent to {@code add(1)}.
75 */
76 public void increment() {
77 add(1L);
78 }
79
80 /**
81 * Equivalent to {@code add(-1)}.
82 */
83 public void decrement() {
84 add(-1L);
85 }
86
87 /**
88 * Returns the current sum. The returned value is <em>NOT</em> an
89 * atomic snapshot; invocation in the absence of concurrent
90 * updates returns an accurate result, but concurrent updates that
91 * occur while the sum is being calculated might not be
92 * incorporated.
93 *
94 * @return the sum
95 */
96 public long sum() {
97 long sum = base;
98 Cell[] as = cells;
99 if (as != null) {
100 int n = as.length;
101 for (int i = 0; i < n; ++i) {
102 Cell a = as[i];
103 if (a != null)
104 sum += a.value;
105 }
106 }
107 return sum;
108 }
109
110 /**
111 * Resets variables maintaining the sum to zero. This method may
112 * be a useful alternative to creating a new adder, but is only
113 * effective if there are no concurrent updates. Because this
114 * method is intrinsically racy, it should only be used when it is
115 * known that no threads are concurrently updating.
116 */
117 public void reset() {
118 internalReset(0L);
119 }
120
121 /**
122 * Equivalent in effect to {@link #sum} followed by {@link
123 * #reset}. This method may apply for example during quiescent
124 * points between multithreaded computations. If there are
125 * updates concurrent with this method, the returned value is
126 * <em>not</em> guaranteed to be the final value occurring before
127 * the reset.
128 *
129 * @return the sum
130 */
131 public long sumThenReset() {
132 long sum = base;
133 Cell[] as = cells;
134 base = 0L;
135 if (as != null) {
136 int n = as.length;
137 for (int i = 0; i < n; ++i) {
138 Cell a = as[i];
139 if (a != null) {
140 sum += a.value;
141 a.value = 0L;
142 }
143 }
144 }
145 return sum;
146 }
147
148 /**
149 * Returns the String representation of the {@link #sum}.
150 * @return the String representation of the {@link #sum}
151 */
152 public String toString() {
153 return Long.toString(sum());
154 }
155
156 /**
157 * Equivalent to {@link #sum}.
158 *
159 * @return the sum
160 */
161 public long longValue() {
162 return sum();
163 }
164
165 /**
166 * Returns the {@link #sum} as an {@code int} after a narrowing
167 * primitive conversion.
168 */
169 public int intValue() {
170 return (int)sum();
171 }
172
173 /**
174 * Returns the {@link #sum} as a {@code float}
175 * after a widening primitive conversion.
176 */
177 public float floatValue() {
178 return (float)sum();
179 }
180
181 /**
182 * Returns the {@link #sum} as a {@code double} after a widening
183 * primitive conversion.
184 */
185 public double doubleValue() {
186 return (double)sum();
187 }
188
189 private void writeObject(ObjectOutputStream s) throws IOException {
190 s.defaultWriteObject();
191 s.writeLong(sum());
192 }
193
194 private void readObject(ObjectInputStream s)
195 throws IOException, ClassNotFoundException {
196 s.defaultReadObject();
197 busy = 0;
198 cells = null;
199 base = s.readLong();
200 }
201
202 }