4 |
|
* http://creativecommons.org/publicdomain/zero/1.0/ |
5 |
|
*/ |
6 |
|
|
7 |
< |
import junit.framework.*; |
8 |
< |
import java.util.concurrent.*; |
7 |
> |
import java.util.concurrent.CyclicBarrier; |
8 |
> |
import java.util.concurrent.Executors; |
9 |
> |
import java.util.concurrent.ExecutorService; |
10 |
|
import java.util.concurrent.atomic.LongAdder; |
11 |
|
|
12 |
+ |
import junit.framework.Test; |
13 |
+ |
import junit.framework.TestSuite; |
14 |
+ |
|
15 |
|
public class LongAdderTest extends JSR166TestCase { |
16 |
|
public static void main(String[] args) { |
17 |
< |
junit.textui.TestRunner.run(suite()); |
17 |
> |
main(suite(), args); |
18 |
|
} |
19 |
|
public static Test suite() { |
20 |
|
return new TestSuite(LongAdderTest.class); |
62 |
|
} |
63 |
|
|
64 |
|
/** |
65 |
< |
* reset zeroes sum |
65 |
> |
* reset() causes subsequent sum() to return zero |
66 |
|
*/ |
67 |
|
public void testReset() { |
68 |
|
LongAdder ai = new LongAdder(); |
73 |
|
} |
74 |
|
|
75 |
|
/** |
76 |
< |
* sumThenReset returns sum then zeros |
76 |
> |
* sumThenReset() returns sum; subsequent sum() returns zero |
77 |
|
*/ |
78 |
|
public void testSumThenReset() { |
79 |
|
LongAdder ai = new LongAdder(); |
151 |
|
/** |
152 |
|
* adds by multiple threads produce correct sum |
153 |
|
*/ |
154 |
< |
public void testAddAndSumMT() { |
154 |
> |
public void testAddAndSumMT() throws Throwable { |
155 |
|
final int incs = 1000000; |
156 |
|
final int nthreads = 4; |
157 |
|
final ExecutorService pool = Executors.newCachedThreadPool(); |
158 |
|
LongAdder a = new LongAdder(); |
159 |
< |
Phaser phaser = new Phaser(nthreads + 1); |
159 |
> |
CyclicBarrier barrier = new CyclicBarrier(nthreads + 1); |
160 |
|
for (int i = 0; i < nthreads; ++i) |
161 |
< |
pool.execute(new AdderTask(a, phaser, incs)); |
162 |
< |
phaser.arriveAndAwaitAdvance(); |
163 |
< |
phaser.arriveAndAwaitAdvance(); |
161 |
> |
pool.execute(new AdderTask(a, barrier, incs)); |
162 |
> |
barrier.await(); |
163 |
> |
barrier.await(); |
164 |
|
long total = (long)nthreads * incs; |
165 |
|
long sum = a.sum(); |
166 |
|
assertEquals(sum, total); |
169 |
|
|
170 |
|
static final class AdderTask implements Runnable { |
171 |
|
final LongAdder adder; |
172 |
< |
final Phaser phaser; |
172 |
> |
final CyclicBarrier barrier; |
173 |
|
final int incs; |
174 |
|
volatile long result; |
175 |
< |
AdderTask(LongAdder adder, Phaser phaser, int incs) { |
175 |
> |
AdderTask(LongAdder adder, CyclicBarrier barrier, int incs) { |
176 |
|
this.adder = adder; |
177 |
< |
this.phaser = phaser; |
177 |
> |
this.barrier = barrier; |
178 |
|
this.incs = incs; |
179 |
|
} |
180 |
|
|
181 |
|
public void run() { |
182 |
< |
phaser.arriveAndAwaitAdvance(); |
183 |
< |
LongAdder a = adder; |
184 |
< |
for (int i = 0; i < incs; ++i) |
185 |
< |
a.add(1L); |
186 |
< |
result = a.sum(); |
187 |
< |
phaser.arrive(); |
182 |
> |
try { |
183 |
> |
barrier.await(); |
184 |
> |
LongAdder a = adder; |
185 |
> |
for (int i = 0; i < incs; ++i) |
186 |
> |
a.add(1L); |
187 |
> |
result = a.sum(); |
188 |
> |
barrier.await(); |
189 |
> |
} catch (Throwable t) { throw new Error(t); } |
190 |
|
} |
191 |
|
} |
192 |
|
|