blob: e061f9a3ff2eda9de9625f2e0a286eeb7b3cddcd [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.Executors;
10import java.util.concurrent.ExecutorService;
11import java.util.concurrent.Phaser;
12import java.util.concurrent.atomic.DoubleAccumulator;
13
14import junit.framework.Test;
15import junit.framework.TestSuite;
16
17public class DoubleAccumulatorTest 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(DoubleAccumulatorTest.class);
26 // }
27
28 /**
29 * default constructed initializes to zero
30 */
31 public void testConstructor() {
32 DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
33 assertEquals(0.0, ai.get());
34 }
35
36 /**
37 * accumulate accumulates given value to current, and get returns current value
38 */
39 public void testAccumulateAndGet() {
40 DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
41 ai.accumulate(2.0);
42 assertEquals(2.0, ai.get());
43 ai.accumulate(-4.0);
44 assertEquals(2.0, ai.get());
45 ai.accumulate(4.0);
46 assertEquals(4.0, ai.get());
47 }
48
49 /**
50 * reset() causes subsequent get() to return zero
51 */
52 public void testReset() {
53 DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
54 ai.accumulate(2.0);
55 assertEquals(2.0, ai.get());
56 ai.reset();
57 assertEquals(0.0, ai.get());
58 }
59
60 /**
61 * getThenReset() returns current value; subsequent get() returns zero
62 */
63 public void testGetThenReset() {
64 DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
65 ai.accumulate(2.0);
66 assertEquals(2.0, ai.get());
67 assertEquals(2.0, ai.getThenReset());
68 assertEquals(0.0, ai.get());
69 }
70
71 /**
72 * toString returns current value.
73 */
74 public void testToString() {
75 DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
76 assertEquals("0.0", ai.toString());
77 ai.accumulate(1.0);
78 assertEquals(Double.toString(1.0), ai.toString());
79 }
80
81 /**
82 * intValue returns current value.
83 */
84 public void testIntValue() {
85 DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
86 assertEquals(0, ai.intValue());
87 ai.accumulate(1.0);
88 assertEquals(1, ai.intValue());
89 }
90
91 /**
92 * longValue returns current value.
93 */
94 public void testLongValue() {
95 DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
96 assertEquals(0, ai.longValue());
97 ai.accumulate(1.0);
98 assertEquals(1, ai.longValue());
99 }
100
101 /**
102 * floatValue returns current value.
103 */
104 public void testFloatValue() {
105 DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
106 assertEquals(0.0f, ai.floatValue());
107 ai.accumulate(1.0);
108 assertEquals(1.0f, ai.floatValue());
109 }
110
111 /**
112 * doubleValue returns current value.
113 */
114 public void testDoubleValue() {
115 DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
116 assertEquals(0.0, ai.doubleValue());
117 ai.accumulate(1.0);
118 assertEquals(1.0, ai.doubleValue());
119 }
120
121 /**
122 * accumulates by multiple threads produce correct result
123 */
124 public void testAccumulateAndGetMT() {
125 final int incs = 1000000;
126 final int nthreads = 4;
127 final ExecutorService pool = Executors.newCachedThreadPool();
128 DoubleAccumulator a = new DoubleAccumulator(Double::max, 0.0);
129 Phaser phaser = new Phaser(nthreads + 1);
130 for (int i = 0; i < nthreads; ++i)
131 pool.execute(new AccTask(a, phaser, incs));
132 phaser.arriveAndAwaitAdvance();
133 phaser.arriveAndAwaitAdvance();
134 double expected = incs - 1;
135 double result = a.get();
136 assertEquals(expected, result);
137 pool.shutdown();
138 }
139
140 static final class AccTask implements Runnable {
141 final DoubleAccumulator acc;
142 final Phaser phaser;
143 final int incs;
144 volatile double result;
145 AccTask(DoubleAccumulator acc, Phaser phaser, int incs) {
146 this.acc = acc;
147 this.phaser = phaser;
148 this.incs = incs;
149 }
150
151 public void run() {
152 phaser.arriveAndAwaitAdvance();
153 DoubleAccumulator a = acc;
154 for (int i = 0; i < incs; ++i)
155 a.accumulate(i);
156 result = a.get();
157 phaser.arrive();
158 }
159 }
160
161}