blob: d02e2a1123b70addbfd3ef630e2f6c752eded2eb [file] [log] [blame]
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001/*
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
7package jsr166;
8
9import java.util.concurrent.CyclicBarrier;
10import java.util.concurrent.Executors;
11import java.util.concurrent.ExecutorService;
12import java.util.concurrent.atomic.DoubleAdder;
13
14import junit.framework.Test;
15import junit.framework.TestSuite;
16
17public class DoubleAdderTest extends JSR166TestCase {
18 // android-note: Removed because the CTS runner does a bad job of
19 // retrying tests that have suite() declarations.
20 //
21 // public static void main(String[] args) {
22 // main(suite(), args);
23 // }
24 // public static Test suite() {
25 // return new TestSuite(DoubleAdderTest.class);
26 // }
27
28 /**
29 * default constructed initializes to zero
30 */
31 public void testConstructor() {
32 DoubleAdder ai = new DoubleAdder();
33 assertEquals(0.0, ai.sum());
34 }
35
36 /**
37 * add adds given value to current, and sum returns current value
38 */
39 public void testAddAndSum() {
40 DoubleAdder ai = new DoubleAdder();
41 ai.add(2.0);
42 assertEquals(2.0, ai.sum());
43 ai.add(-4.0);
44 assertEquals(-2.0, ai.sum());
45 }
46
47 /**
48 * reset() causes subsequent sum() to return zero
49 */
50 public void testReset() {
51 DoubleAdder ai = new DoubleAdder();
52 ai.add(2.0);
53 assertEquals(2.0, ai.sum());
54 ai.reset();
55 assertEquals(0.0, ai.sum());
56 }
57
58 /**
59 * sumThenReset() returns sum; subsequent sum() returns zero
60 */
61 public void testSumThenReset() {
62 DoubleAdder ai = new DoubleAdder();
63 ai.add(2.0);
64 assertEquals(2.0, ai.sum());
65 assertEquals(2.0, ai.sumThenReset());
66 assertEquals(0.0, ai.sum());
67 }
68
69 /**
70 * a deserialized serialized adder holds same value
71 */
72 public void testSerialization() throws Exception {
73 DoubleAdder x = new DoubleAdder();
74 DoubleAdder y = serialClone(x);
75 assertNotSame(x, y);
76 x.add(-22.0);
77 DoubleAdder z = serialClone(x);
78 assertEquals(-22.0, x.sum());
79 assertEquals(0.0, y.sum());
80 assertEquals(-22.0, z.sum());
81 }
82
83 /**
84 * toString returns current value.
85 */
86 public void testToString() {
87 DoubleAdder ai = new DoubleAdder();
88 assertEquals(Double.toString(0.0), ai.toString());
89 ai.add(1.0);
90 assertEquals(Double.toString(1.0), ai.toString());
91 }
92
93 /**
94 * intValue returns current value.
95 */
96 public void testIntValue() {
97 DoubleAdder ai = new DoubleAdder();
98 assertEquals(0, ai.intValue());
99 ai.add(1.0);
100 assertEquals(1, ai.intValue());
101 }
102
103 /**
104 * longValue returns current value.
105 */
106 public void testLongValue() {
107 DoubleAdder ai = new DoubleAdder();
108 assertEquals(0, ai.longValue());
109 ai.add(1.0);
110 assertEquals(1, ai.longValue());
111 }
112
113 /**
114 * floatValue returns current value.
115 */
116 public void testFloatValue() {
117 DoubleAdder ai = new DoubleAdder();
118 assertEquals(0.0f, ai.floatValue());
119 ai.add(1.0);
120 assertEquals(1.0f, ai.floatValue());
121 }
122
123 /**
124 * doubleValue returns current value.
125 */
126 public void testDoubleValue() {
127 DoubleAdder ai = new DoubleAdder();
128 assertEquals(0.0, ai.doubleValue());
129 ai.add(1.0);
130 assertEquals(1.0, ai.doubleValue());
131 }
132
133 /**
134 * adds by multiple threads produce correct sum
135 */
136 public void testAddAndSumMT() throws Throwable {
137 final int incs = 1000000;
138 final int nthreads = 4;
139 final ExecutorService pool = Executors.newCachedThreadPool();
140 DoubleAdder a = new DoubleAdder();
141 CyclicBarrier barrier = new CyclicBarrier(nthreads + 1);
142 for (int i = 0; i < nthreads; ++i)
143 pool.execute(new AdderTask(a, barrier, incs));
144 barrier.await();
145 barrier.await();
146 double total = (long)nthreads * incs;
147 double sum = a.sum();
148 assertEquals(sum, total);
149 pool.shutdown();
150 }
151
152 static final class AdderTask implements Runnable {
153 final DoubleAdder adder;
154 final CyclicBarrier barrier;
155 final int incs;
156 volatile double result;
157 AdderTask(DoubleAdder adder, CyclicBarrier barrier, int incs) {
158 this.adder = adder;
159 this.barrier = barrier;
160 this.incs = incs;
161 }
162
163 public void run() {
164 try {
165 barrier.await();
166 DoubleAdder a = adder;
167 for (int i = 0; i < incs; ++i)
168 a.add(1.0);
169 result = a.sum();
170 barrier.await();
171 } catch (Throwable t) { throw new Error(t); }
172 }
173 }
174
175}