140 |
|
static final ThreadHashCode threadHashCode = new ThreadHashCode(); |
141 |
|
|
142 |
|
/** |
143 |
< |
* Table of adders. Size is power of two, grows to be at most CAP. |
143 |
> |
* Common placeholder for empty arrays. |
144 |
> |
*/ |
145 |
> |
static final Adder[] EMPTY_ARRAY = new Adder[0]; |
146 |
> |
|
147 |
> |
/** |
148 |
> |
* Table of adders. Size is either zero or a power of two, grows |
149 |
> |
* to be at most CAP. |
150 |
|
*/ |
151 |
|
private transient volatile Adder[] adders; |
152 |
|
|
163 |
|
* Creates a new adder with zero sum. |
164 |
|
*/ |
165 |
|
public StripedAdder() { |
166 |
+ |
this.adders = EMPTY_ARRAY; |
167 |
|
this.mutex = new AtomicInteger(); |
168 |
|
// remaining initialization on first call to add. |
169 |
|
} |
176 |
|
* will concurrently update the sum. |
177 |
|
*/ |
178 |
|
public StripedAdder(int expectedContention) { |
179 |
< |
int cap = (expectedContention < CAP) ? expectedContention : CAP; |
180 |
< |
int size = 1; |
181 |
< |
while (size < cap) |
182 |
< |
size <<= 1; |
183 |
< |
Adder[] as = new Adder[size]; |
184 |
< |
for (int i = 0; i < size; ++i) |
185 |
< |
as[i] = new Adder(0); |
186 |
< |
this.adders = as; |
179 |
> |
if (expectedContention > 0) { |
180 |
> |
int cap = (expectedContention < CAP) ? expectedContention : CAP; |
181 |
> |
int size = 1; |
182 |
> |
while (size < cap) |
183 |
> |
size <<= 1; |
184 |
> |
Adder[] as = new Adder[size]; |
185 |
> |
for (int i = 0; i < size; ++i) |
186 |
> |
as[i] = new Adder(0); |
187 |
> |
this.adders = as; |
188 |
> |
} |
189 |
> |
else |
190 |
> |
this.adders = EMPTY_ARRAY; |
191 |
|
this.mutex = new AtomicInteger(); |
192 |
|
} |
193 |
|
|
219 |
|
Adder[] as; Adder a; long v; int k, n; |
220 |
|
while ((as = adders) == null || (n = as.length) < 1) { |
221 |
|
synchronized(mutex) { // Try to initialize |
222 |
< |
if (adders == null) { |
222 |
> |
if (adders == as) { |
223 |
|
Adder[] rs = new Adder[DEFAULT_INITIAL_SIZE]; |
224 |
|
rs[h & (DEFAULT_INITIAL_SIZE - 1)] = new Adder(0); |
225 |
|
adders = rs; |