ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/DoubleAccumulatorTest.java
(Generate patch)

Comparing jsr166/src/test/tck/DoubleAccumulatorTest.java (file contents):
Revision 1.3 by jsr166, Wed Dec 31 19:05:42 2014 UTC vs.
Revision 1.8 by jsr166, Sun Apr 23 04:08:48 2017 UTC

# Line 7 | Line 7
7   import java.util.concurrent.Executors;
8   import java.util.concurrent.ExecutorService;
9   import java.util.concurrent.Phaser;
10 + import java.util.concurrent.ThreadLocalRandom;
11   import java.util.concurrent.atomic.DoubleAccumulator;
12  
13   import junit.framework.Test;
# Line 14 | Line 15 | import junit.framework.TestSuite;
15  
16   public class DoubleAccumulatorTest extends JSR166TestCase {
17      public static void main(String[] args) {
18 <        junit.textui.TestRunner.run(suite());
18 >        main(suite(), args);
19      }
20      public static Test suite() {
21          return new TestSuite(DoubleAccumulatorTest.class);
22      }
23  
24      /**
25 <     * default constructed initializes to zero
25 >     * new instance initialized to supplied identity
26       */
27      public void testConstructor() {
28 <        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
29 <        assertEquals(0.0, ai.get());
28 >        for (double identity : new double[] {
29 >                 Double.NEGATIVE_INFINITY,
30 >                 Double.POSITIVE_INFINITY,
31 >                 Double.MIN_VALUE,
32 >                 Double.MAX_VALUE,
33 >                 0.0,
34 >             })
35 >            assertEquals(identity,
36 >                         new DoubleAccumulator(Double::max, identity).get());
37      }
38  
39      /**
40       * accumulate accumulates given value to current, and get returns current value
41       */
42      public void testAccumulateAndGet() {
43 <        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
44 <        ai.accumulate(2.0);
45 <        assertEquals(2.0, ai.get());
46 <        ai.accumulate(-4.0);
47 <        assertEquals(2.0, ai.get());
48 <        ai.accumulate(4.0);
49 <        assertEquals(4.0, ai.get());
43 >        DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
44 >        acc.accumulate(2.0);
45 >        assertEquals(2.0, acc.get());
46 >        acc.accumulate(-4.0);
47 >        assertEquals(2.0, acc.get());
48 >        acc.accumulate(4.0);
49 >        assertEquals(4.0, acc.get());
50      }
51  
52      /**
53 <     * reset zeroes get
53 >     * reset() causes subsequent get() to return zero
54       */
55      public void testReset() {
56 <        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
57 <        ai.accumulate(2.0);
58 <        assertEquals(2.0, ai.get());
59 <        ai.reset();
60 <        assertEquals(0.0, ai.get());
56 >        DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
57 >        acc.accumulate(2.0);
58 >        assertEquals(2.0, acc.get());
59 >        acc.reset();
60 >        assertEquals(0.0, acc.get());
61      }
62  
63      /**
64 <     * getThenReset returns get then zeros
64 >     * getThenReset() returns current value; subsequent get() returns zero
65       */
66      public void testGetThenReset() {
67 <        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
68 <        ai.accumulate(2.0);
69 <        assertEquals(2.0, ai.get());
70 <        assertEquals(2.0, ai.getThenReset());
71 <        assertEquals(0.0, ai.get());
67 >        DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
68 >        acc.accumulate(2.0);
69 >        assertEquals(2.0, acc.get());
70 >        assertEquals(2.0, acc.getThenReset());
71 >        assertEquals(0.0, acc.get());
72      }
73  
74      /**
75       * toString returns current value.
76       */
77      public void testToString() {
78 <        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
79 <        assertEquals("0.0", ai.toString());
80 <        ai.accumulate(1.0);
81 <        assertEquals(Double.toString(1.0), ai.toString());
78 >        DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
79 >        assertEquals("0.0", acc.toString());
80 >        acc.accumulate(1.0);
81 >        assertEquals(Double.toString(1.0), acc.toString());
82      }
83  
84      /**
85       * intValue returns current value.
86       */
87      public void testIntValue() {
88 <        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
89 <        assertEquals(0, ai.intValue());
90 <        ai.accumulate(1.0);
91 <        assertEquals(1, ai.intValue());
88 >        DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
89 >        assertEquals(0, acc.intValue());
90 >        acc.accumulate(1.0);
91 >        assertEquals(1, acc.intValue());
92      }
93  
94      /**
95       * longValue returns current value.
96       */
97      public void testLongValue() {
98 <        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
99 <        assertEquals(0, ai.longValue());
100 <        ai.accumulate(1.0);
101 <        assertEquals(1, ai.longValue());
98 >        DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
99 >        assertEquals(0, acc.longValue());
100 >        acc.accumulate(1.0);
101 >        assertEquals(1, acc.longValue());
102      }
103  
104      /**
105       * floatValue returns current value.
106       */
107      public void testFloatValue() {
108 <        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
109 <        assertEquals(0.0f, ai.floatValue());
110 <        ai.accumulate(1.0);
111 <        assertEquals(1.0f, ai.floatValue());
108 >        DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
109 >        assertEquals(0.0f, acc.floatValue());
110 >        acc.accumulate(1.0);
111 >        assertEquals(1.0f, acc.floatValue());
112      }
113  
114      /**
115       * doubleValue returns current value.
116       */
117      public void testDoubleValue() {
118 <        DoubleAccumulator ai = new DoubleAccumulator(Double::max, 0.0);
119 <        assertEquals(0.0, ai.doubleValue());
120 <        ai.accumulate(1.0);
121 <        assertEquals(1.0, ai.doubleValue());
118 >        DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0);
119 >        assertEquals(0.0, acc.doubleValue());
120 >        acc.accumulate(1.0);
121 >        assertEquals(1.0, acc.doubleValue());
122      }
123  
124      /**
125       * accumulates by multiple threads produce correct result
126       */
127      public void testAccumulateAndGetMT() {
128 <        final int incs = 1000000;
129 <        final int nthreads = 4;
130 <        final ExecutorService pool = Executors.newCachedThreadPool();
131 <        DoubleAccumulator a = new DoubleAccumulator(Double::max, 0.0);
132 <        Phaser phaser = new Phaser(nthreads + 1);
133 <        for (int i = 0; i < nthreads; ++i)
134 <            pool.execute(new AccTask(a, phaser, incs));
127 <        phaser.arriveAndAwaitAdvance();
128 <        phaser.arriveAndAwaitAdvance();
129 <        double expected = incs - 1;
130 <        double result = a.get();
131 <        assertEquals(expected, result);
132 <        pool.shutdown();
133 <    }
134 <
135 <    static final class AccTask implements Runnable {
136 <        final DoubleAccumulator acc;
137 <        final Phaser phaser;
138 <        final int incs;
139 <        volatile double result;
140 <        AccTask(DoubleAccumulator acc, Phaser phaser, int incs) {
141 <            this.acc = acc;
142 <            this.phaser = phaser;
143 <            this.incs = incs;
144 <        }
145 <
146 <        public void run() {
128 >        final DoubleAccumulator acc
129 >            = new DoubleAccumulator((x, y) -> x + y, 0.0);
130 >        final int nThreads = ThreadLocalRandom.current().nextInt(1, 5);
131 >        final Phaser phaser = new Phaser(nThreads + 1);
132 >        final int incs = 1_000_000;
133 >        final double total = nThreads * incs/2.0 * (incs - 1); // Gauss
134 >        final Runnable task = () -> {
135              phaser.arriveAndAwaitAdvance();
136 <            DoubleAccumulator a = acc;
137 <            for (int i = 0; i < incs; ++i)
138 <                a.accumulate(i);
139 <            result = a.get();
136 >            for (int i = 0; i < incs; i++) {
137 >                acc.accumulate((double) i);
138 >                assertTrue(acc.get() <= total);
139 >            }
140              phaser.arrive();
141 +        };
142 +        final ExecutorService p = Executors.newCachedThreadPool();
143 +        try (PoolCleaner cleaner = cleaner(p)) {
144 +            for (int i = nThreads; i-->0; )
145 +                p.execute(task);
146 +            phaser.arriveAndAwaitAdvance();
147 +            phaser.arriveAndAwaitAdvance();
148 +            assertEquals(total, acc.get());
149          }
150      }
151  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines