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.LongAccumulator; 39 40 import junit.framework.Test; 41 import junit.framework.TestSuite; 42 43 public class LongAccumulatorTest extends JSR166TestCase { 44 public static void main(String[] args) { 45 main(suite(), args); 46 } 47 public static Test suite() { 48 return new TestSuite(LongAccumulatorTest.class); 49 } 50 51 /** 52 * new instance initialized to supplied identity 53 */ 54 public void testConstructor() { 55 for (long identity : new long[] { Long.MIN_VALUE, 0, Long.MAX_VALUE }) 56 assertEquals(identity, 57 new LongAccumulator(Long::max, identity).get()); 58 } 59 60 /** 61 * accumulate accumulates given value to current, and get returns current value 62 */ 63 public void testAccumulateAndGet() { 64 LongAccumulator acc = new LongAccumulator(Long::max, 0L); 65 acc.accumulate(2); 66 assertEquals(2, acc.get()); 67 acc.accumulate(-4); 68 assertEquals(2, acc.get()); 69 acc.accumulate(4); 70 assertEquals(4, acc.get()); 71 } 72 73 /** 74 * reset() causes subsequent get() to return zero 75 */ 76 public void testReset() { 77 LongAccumulator acc = new LongAccumulator(Long::max, 0L); 78 acc.accumulate(2); 79 assertEquals(2, acc.get()); 80 acc.reset(); 81 assertEquals(0, acc.get()); 82 } 83 84 /** 85 * getThenReset() returns current value; subsequent get() returns zero 86 */ 87 public void testGetThenReset() { 88 LongAccumulator acc = new LongAccumulator(Long::max, 0L); 89 acc.accumulate(2); 90 assertEquals(2, acc.get()); 91 assertEquals(2, acc.getThenReset()); 92 assertEquals(0, acc.get()); 93 } 94 95 /** 96 * toString returns current value. 97 */ 98 public void testToString() { 99 LongAccumulator acc = new LongAccumulator(Long::max, 0L); 100 assertEquals("0", acc.toString()); 101 acc.accumulate(1); 102 assertEquals(Long.toString(1), acc.toString()); 103 } 104 105 /** 106 * intValue returns current value. 107 */ 108 public void testIntValue() { 109 LongAccumulator acc = new LongAccumulator(Long::max, 0L); 110 assertEquals(0, acc.intValue()); 111 acc.accumulate(1); 112 assertEquals(1, acc.intValue()); 113 } 114 115 /** 116 * longValue returns current value. 117 */ 118 public void testLongValue() { 119 LongAccumulator acc = new LongAccumulator(Long::max, 0L); 120 assertEquals(0, acc.longValue()); 121 acc.accumulate(1); 122 assertEquals(1, acc.longValue()); 123 } 124 125 /** 126 * floatValue returns current value. 127 */ 128 public void testFloatValue() { 129 LongAccumulator acc = new LongAccumulator(Long::max, 0L); 130 assertEquals(0.0f, acc.floatValue()); 131 acc.accumulate(1); 132 assertEquals(1.0f, acc.floatValue()); 133 } 134 135 /** 136 * doubleValue returns current value. 137 */ 138 public void testDoubleValue() { 139 LongAccumulator acc = new LongAccumulator(Long::max, 0L); 140 assertEquals(0.0, acc.doubleValue()); 141 acc.accumulate(1); 142 assertEquals(1.0, acc.doubleValue()); 143 } 144 145 /** 146 * accumulates by multiple threads produce correct result 147 */ 148 public void testAccumulateAndGetMT() { 149 final LongAccumulator acc 150 = new LongAccumulator((x, y) -> x + y, 0L); 151 final int nThreads = ThreadLocalRandom.current().nextInt(1, 5); 152 final Phaser phaser = new Phaser(nThreads + 1); 153 final int incs = expensiveTests ? 1_000_000 : 100_000; 154 final long total = nThreads * incs/2L * (incs - 1); // Gauss 155 final Runnable task = () -> { 156 phaser.arriveAndAwaitAdvance(); 157 for (int i = 0; i < incs; i++) { 158 acc.accumulate((long) i); 159 assertTrue(acc.get() <= total); 160 } 161 phaser.arrive(); 162 }; 163 final ExecutorService p = Executors.newCachedThreadPool(); 164 try (PoolCleaner cleaner = cleaner(p)) { 165 for (int i = nThreads; i-->0; ) 166 p.execute(task); 167 phaser.arriveAndAwaitAdvance(); 168 phaser.arriveAndAwaitAdvance(); 169 assertEquals(total, acc.get()); 170 } 171 } 172 173 }