1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea with assistance from members of JCP JSR-166 30 * Expert Group and released to the public domain, as explained at 31 * http://creativecommons.org/publicdomain/zero/1.0/ 32 */ 33 34 import java.util.concurrent.Executors; 35 import java.util.concurrent.ExecutorService; 36 import java.util.concurrent.Phaser; 37 import java.util.concurrent.ThreadLocalRandom; 38 import java.util.concurrent.atomic.DoubleAccumulator; 39 40 import junit.framework.Test; 41 import junit.framework.TestSuite; 42 43 public class DoubleAccumulatorTest extends JSR166TestCase { 44 public static void main(String[] args) { 45 main(suite(), args); 46 } 47 public static Test suite() { 48 return new TestSuite(DoubleAccumulatorTest.class); 49 } 50 51 /** 52 * new instance initialized to supplied identity 53 */ 54 public void testConstructor() { 55 for (double identity : new double[] { 56 Double.NEGATIVE_INFINITY, 57 Double.POSITIVE_INFINITY, 58 Double.MIN_VALUE, 59 Double.MAX_VALUE, 60 0.0, 61 }) 62 assertEquals(identity, 63 new DoubleAccumulator(Double::max, identity).get()); 64 } 65 66 /** 67 * accumulate accumulates given value to current, and get returns current value 68 */ 69 public void testAccumulateAndGet() { 70 DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0); 71 acc.accumulate(2.0); 72 assertEquals(2.0, acc.get()); 73 acc.accumulate(-4.0); 74 assertEquals(2.0, acc.get()); 75 acc.accumulate(4.0); 76 assertEquals(4.0, acc.get()); 77 } 78 79 /** 80 * reset() causes subsequent get() to return zero 81 */ 82 public void testReset() { 83 DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0); 84 acc.accumulate(2.0); 85 assertEquals(2.0, acc.get()); 86 acc.reset(); 87 assertEquals(0.0, acc.get()); 88 } 89 90 /** 91 * getThenReset() returns current value; subsequent get() returns zero 92 */ 93 public void testGetThenReset() { 94 DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0); 95 acc.accumulate(2.0); 96 assertEquals(2.0, acc.get()); 97 assertEquals(2.0, acc.getThenReset()); 98 assertEquals(0.0, acc.get()); 99 } 100 101 /** 102 * toString returns current value. 103 */ 104 public void testToString() { 105 DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0); 106 assertEquals("0.0", acc.toString()); 107 acc.accumulate(1.0); 108 assertEquals(Double.toString(1.0), acc.toString()); 109 } 110 111 /** 112 * intValue returns current value. 113 */ 114 public void testIntValue() { 115 DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0); 116 assertEquals(0, acc.intValue()); 117 acc.accumulate(1.0); 118 assertEquals(1, acc.intValue()); 119 } 120 121 /** 122 * longValue returns current value. 123 */ 124 public void testLongValue() { 125 DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0); 126 assertEquals(0, acc.longValue()); 127 acc.accumulate(1.0); 128 assertEquals(1, acc.longValue()); 129 } 130 131 /** 132 * floatValue returns current value. 133 */ 134 public void testFloatValue() { 135 DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0); 136 assertEquals(0.0f, acc.floatValue()); 137 acc.accumulate(1.0); 138 assertEquals(1.0f, acc.floatValue()); 139 } 140 141 /** 142 * doubleValue returns current value. 143 */ 144 public void testDoubleValue() { 145 DoubleAccumulator acc = new DoubleAccumulator(Double::max, 0.0); 146 assertEquals(0.0, acc.doubleValue()); 147 acc.accumulate(1.0); 148 assertEquals(1.0, acc.doubleValue()); 149 } 150 151 /** 152 * accumulates by multiple threads produce correct result 153 */ 154 public void testAccumulateAndGetMT() { 155 final DoubleAccumulator acc 156 = new DoubleAccumulator((x, y) -> x + y, 0.0); 157 final int nThreads = ThreadLocalRandom.current().nextInt(1, 5); 158 final Phaser phaser = new Phaser(nThreads + 1); 159 final int incs = expensiveTests ? 1_000_000 : 100_000; 160 final double total = nThreads * incs/2.0 * (incs - 1); // Gauss 161 final Runnable task = () -> { 162 phaser.arriveAndAwaitAdvance(); 163 for (int i = 0; i < incs; i++) { 164 acc.accumulate((double) i); 165 assertTrue(acc.get() <= total); 166 } 167 phaser.arrive(); 168 }; 169 final ExecutorService p = Executors.newCachedThreadPool(); 170 try (PoolCleaner cleaner = cleaner(p)) { 171 for (int i = nThreads; i-->0; ) 172 p.execute(task); 173 phaser.arriveAndAwaitAdvance(); 174 phaser.arriveAndAwaitAdvance(); 175 assertEquals(total, acc.get()); 176 } 177 } 178 179 }