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 7package jsr166; 8 9import java.util.concurrent.Executors; 10import java.util.concurrent.ExecutorService; 11import java.util.concurrent.Phaser; 12import java.util.concurrent.atomic.LongAccumulator; 13 14import junit.framework.Test; 15import junit.framework.TestSuite; 16 17public class LongAccumulatorTest 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(LongAccumulatorTest.class); 26 // } 27 28 /** 29 * default constructed initializes to zero 30 */ 31 public void testConstructor() { 32 LongAccumulator ai = new LongAccumulator(Long::max, 0L); 33 assertEquals(0, ai.get()); 34 } 35 36 /** 37 * accumulate accumulates given value to current, and get returns current value 38 */ 39 public void testAccumulateAndGet() { 40 LongAccumulator ai = new LongAccumulator(Long::max, 0L); 41 ai.accumulate(2); 42 assertEquals(2, ai.get()); 43 ai.accumulate(-4); 44 assertEquals(2, ai.get()); 45 ai.accumulate(4); 46 assertEquals(4, ai.get()); 47 } 48 49 /** 50 * reset() causes subsequent get() to return zero 51 */ 52 public void testReset() { 53 LongAccumulator ai = new LongAccumulator(Long::max, 0L); 54 ai.accumulate(2); 55 assertEquals(2, ai.get()); 56 ai.reset(); 57 assertEquals(0, ai.get()); 58 } 59 60 /** 61 * getThenReset() returns current value; subsequent get() returns zero 62 */ 63 public void testGetThenReset() { 64 LongAccumulator ai = new LongAccumulator(Long::max, 0L); 65 ai.accumulate(2); 66 assertEquals(2, ai.get()); 67 assertEquals(2, ai.getThenReset()); 68 assertEquals(0, ai.get()); 69 } 70 71 /** 72 * toString returns current value. 73 */ 74 public void testToString() { 75 LongAccumulator ai = new LongAccumulator(Long::max, 0L); 76 assertEquals("0", ai.toString()); 77 ai.accumulate(1); 78 assertEquals(Long.toString(1), ai.toString()); 79 } 80 81 /** 82 * intValue returns current value. 83 */ 84 public void testIntValue() { 85 LongAccumulator ai = new LongAccumulator(Long::max, 0L); 86 assertEquals(0, ai.intValue()); 87 ai.accumulate(1); 88 assertEquals(1, ai.intValue()); 89 } 90 91 /** 92 * longValue returns current value. 93 */ 94 public void testLongValue() { 95 LongAccumulator ai = new LongAccumulator(Long::max, 0L); 96 assertEquals(0, ai.longValue()); 97 ai.accumulate(1); 98 assertEquals(1, ai.longValue()); 99 } 100 101 /** 102 * floatValue returns current value. 103 */ 104 public void testFloatValue() { 105 LongAccumulator ai = new LongAccumulator(Long::max, 0L); 106 assertEquals(0.0f, ai.floatValue()); 107 ai.accumulate(1); 108 assertEquals(1.0f, ai.floatValue()); 109 } 110 111 /** 112 * doubleValue returns current value. 113 */ 114 public void testDoubleValue() { 115 LongAccumulator ai = new LongAccumulator(Long::max, 0L); 116 assertEquals(0.0, ai.doubleValue()); 117 ai.accumulate(1); 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 LongAccumulator a = new LongAccumulator(Long::max, 0L); 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 long expected = incs - 1; 135 long result = a.get(); 136 assertEquals(expected, result); 137 pool.shutdown(); 138 } 139 140 static final class AccTask implements Runnable { 141 final LongAccumulator acc; 142 final Phaser phaser; 143 final int incs; 144 volatile long result; 145 AccTask(LongAccumulator 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 LongAccumulator 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