ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/jsr166e/LongAdder.java
Revision: 1.14
Committed: Mon Jan 14 02:02:41 2013 UTC (11 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.13: +1 -1 lines
Log Message:
punctuation

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