1 /* 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 7 package jsr166; 8 9 import java.util.concurrent.Executors; 10 import java.util.concurrent.ExecutorService; 11 import java.util.concurrent.Phaser; 12 import java.util.concurrent.atomic.DoubleAccumulator; 13 14 import junit.framework.Test; 15 import junit.framework.TestSuite; 16 17 public 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 */ testConstructor()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 */ testAccumulateAndGet()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 */ testReset()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 */ testGetThenReset()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 */ testToString()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 */ testIntValue()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 */ testLongValue()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 */ testFloatValue()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 */ testDoubleValue()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 */ testAccumulateAndGetMT()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; AccTask(DoubleAccumulator acc, Phaser phaser, int incs)145 AccTask(DoubleAccumulator acc, Phaser phaser, int incs) { 146 this.acc = acc; 147 this.phaser = phaser; 148 this.incs = incs; 149 } 150 run()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 } 162