LongAccumulatorTest.java revision 13564:1f4febd3c93d
1219820Sjeff/* 2219820Sjeff * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3219820Sjeff * 4219820Sjeff * This code is free software; you can redistribute it and/or modify it 5219820Sjeff * under the terms of the GNU General Public License version 2 only, as 6219820Sjeff * published by the Free Software Foundation. 7219820Sjeff * 8219820Sjeff * This code is distributed in the hope that it will be useful, but WITHOUT 9219820Sjeff * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10219820Sjeff * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11219820Sjeff * version 2 for more details (a copy is included in the LICENSE file that 12219820Sjeff * accompanied this code). 13219820Sjeff * 14219820Sjeff * You should have received a copy of the GNU General Public License version 15219820Sjeff * 2 along with this work; if not, write to the Free Software Foundation, 16219820Sjeff * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17219820Sjeff * 18219820Sjeff * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19219820Sjeff * or visit www.oracle.com if you need additional information or have any 20219820Sjeff * questions. 21219820Sjeff */ 22219820Sjeff 23219820Sjeff/* 24219820Sjeff * This file is available under and governed by the GNU General Public 25219820Sjeff * License version 2 only, as published by the Free Software Foundation. 26219820Sjeff * However, the following notice accompanied the original version of this 27219820Sjeff * file: 28219820Sjeff * 29219820Sjeff * Written by Doug Lea with assistance from members of JCP JSR-166 30219820Sjeff * Expert Group and released to the public domain, as explained at 31219820Sjeff * http://creativecommons.org/publicdomain/zero/1.0/ 32219820Sjeff */ 33219820Sjeff 34219820Sjeffimport java.util.concurrent.Executors; 35219820Sjeffimport java.util.concurrent.ExecutorService; 36219820Sjeffimport java.util.concurrent.Phaser; 37219820Sjeffimport java.util.concurrent.atomic.LongAccumulator; 38219820Sjeff 39219820Sjeffimport junit.framework.Test; 40219820Sjeffimport junit.framework.TestSuite; 41219820Sjeff 42219820Sjeffpublic class LongAccumulatorTest extends JSR166TestCase { 43219820Sjeff public static void main(String[] args) { 44219820Sjeff main(suite(), args); 45219820Sjeff } 46219820Sjeff public static Test suite() { 47219820Sjeff return new TestSuite(LongAccumulatorTest.class); 48219820Sjeff } 49219820Sjeff 50219820Sjeff /** 51219820Sjeff * default constructed initializes to zero 52219820Sjeff */ 53219820Sjeff public void testConstructor() { 54219820Sjeff LongAccumulator ai = new LongAccumulator(Long::max, 0L); 55219820Sjeff assertEquals(0, ai.get()); 56219820Sjeff } 57219820Sjeff 58219820Sjeff /** 59219820Sjeff * accumulate accumulates given value to current, and get returns current value 60219820Sjeff */ 61219820Sjeff public void testAccumulateAndGet() { 62219820Sjeff LongAccumulator ai = new LongAccumulator(Long::max, 0L); 63219820Sjeff ai.accumulate(2); 64219820Sjeff assertEquals(2, ai.get()); 65219820Sjeff ai.accumulate(-4); 66219820Sjeff assertEquals(2, ai.get()); 67219820Sjeff ai.accumulate(4); 68219820Sjeff assertEquals(4, ai.get()); 69219820Sjeff } 70219820Sjeff 71219820Sjeff /** 72219820Sjeff * reset() causes subsequent get() to return zero 73219820Sjeff */ 74219820Sjeff public void testReset() { 75219820Sjeff LongAccumulator ai = new LongAccumulator(Long::max, 0L); 76219820Sjeff ai.accumulate(2); 77219820Sjeff assertEquals(2, ai.get()); 78219820Sjeff ai.reset(); 79219820Sjeff assertEquals(0, ai.get()); 80219820Sjeff } 81219820Sjeff 82219820Sjeff /** 83219820Sjeff * getThenReset() returns current value; subsequent get() returns zero 84219820Sjeff */ 85219820Sjeff public void testGetThenReset() { 86219820Sjeff LongAccumulator ai = new LongAccumulator(Long::max, 0L); 87219820Sjeff ai.accumulate(2); 88219820Sjeff assertEquals(2, ai.get()); 89219820Sjeff assertEquals(2, ai.getThenReset()); 90219820Sjeff assertEquals(0, ai.get()); 91219820Sjeff } 92219820Sjeff 93219820Sjeff /** 94219820Sjeff * toString returns current value. 95219820Sjeff */ 96219820Sjeff public void testToString() { 97219820Sjeff LongAccumulator ai = new LongAccumulator(Long::max, 0L); 98219820Sjeff assertEquals("0", ai.toString()); 99219820Sjeff ai.accumulate(1); 100219820Sjeff assertEquals(Long.toString(1), ai.toString()); 101219820Sjeff } 102219820Sjeff 103219820Sjeff /** 104219820Sjeff * intValue returns current value. 105219820Sjeff */ 106219820Sjeff public void testIntValue() { 107219820Sjeff LongAccumulator ai = new LongAccumulator(Long::max, 0L); 108219820Sjeff assertEquals(0, ai.intValue()); 109219820Sjeff ai.accumulate(1); 110219820Sjeff assertEquals(1, ai.intValue()); 111219820Sjeff } 112219820Sjeff 113219820Sjeff /** 114219820Sjeff * longValue returns current value. 115219820Sjeff */ 116219820Sjeff public void testLongValue() { 117219820Sjeff LongAccumulator ai = new LongAccumulator(Long::max, 0L); 118219820Sjeff assertEquals(0, ai.longValue()); 119219820Sjeff ai.accumulate(1); 120219820Sjeff assertEquals(1, ai.longValue()); 121219820Sjeff } 122219820Sjeff 123219820Sjeff /** 124219820Sjeff * floatValue returns current value. 125219820Sjeff */ 126219820Sjeff public void testFloatValue() { 127219820Sjeff LongAccumulator ai = new LongAccumulator(Long::max, 0L); 128219820Sjeff assertEquals(0.0f, ai.floatValue()); 129219820Sjeff ai.accumulate(1); 130219820Sjeff assertEquals(1.0f, ai.floatValue()); 131219820Sjeff } 132219820Sjeff 133219820Sjeff /** 134219820Sjeff * doubleValue returns current value. 135219820Sjeff */ 136219820Sjeff public void testDoubleValue() { 137219820Sjeff LongAccumulator ai = new LongAccumulator(Long::max, 0L); 138219820Sjeff assertEquals(0.0, ai.doubleValue()); 139219820Sjeff ai.accumulate(1); 140219820Sjeff assertEquals(1.0, ai.doubleValue()); 141219820Sjeff } 142219820Sjeff 143219820Sjeff /** 144219820Sjeff * accumulates by multiple threads produce correct result 145219820Sjeff */ 146219820Sjeff public void testAccumulateAndGetMT() { 147219820Sjeff final int incs = 1000000; 148219820Sjeff final int nthreads = 4; 149219820Sjeff final ExecutorService pool = Executors.newCachedThreadPool(); 150219820Sjeff LongAccumulator a = new LongAccumulator(Long::max, 0L); 151219820Sjeff Phaser phaser = new Phaser(nthreads + 1); 152219820Sjeff for (int i = 0; i < nthreads; ++i) 153219820Sjeff pool.execute(new AccTask(a, phaser, incs)); 154219820Sjeff phaser.arriveAndAwaitAdvance(); 155219820Sjeff phaser.arriveAndAwaitAdvance(); 156219820Sjeff long expected = incs - 1; 157219820Sjeff long result = a.get(); 158219820Sjeff assertEquals(expected, result); 159219820Sjeff pool.shutdown(); 160219820Sjeff } 161219820Sjeff 162219820Sjeff static final class AccTask implements Runnable { 163219820Sjeff final LongAccumulator acc; 164219820Sjeff final Phaser phaser; 165219820Sjeff final int incs; 166219820Sjeff volatile long result; 167219820Sjeff AccTask(LongAccumulator acc, Phaser phaser, int incs) { 168219820Sjeff this.acc = acc; 169219820Sjeff this.phaser = phaser; 170219820Sjeff this.incs = incs; 171219820Sjeff } 172219820Sjeff 173219820Sjeff public void run() { 174219820Sjeff phaser.arriveAndAwaitAdvance(); 175219820Sjeff LongAccumulator a = acc; 176219820Sjeff for (int i = 0; i < incs; ++i) 177219820Sjeff a.accumulate(i); 178219820Sjeff result = a.get(); 179219820Sjeff phaser.arrive(); 180219820Sjeff } 181219820Sjeff } 182219820Sjeff 183219820Sjeff} 184219820Sjeff