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 34import java.util.concurrent.ThreadLocalRandom; 35import java.util.concurrent.atomic.AtomicInteger; 36import java.util.concurrent.atomic.LongAdder; 37 38import junit.framework.Test; 39import junit.framework.TestSuite; 40 41public class ThreadLocalRandom8Test extends JSR166TestCase { 42 43 public static void main(String[] args) { 44 main(suite(), args); 45 } 46 public static Test suite() { 47 return new TestSuite(ThreadLocalRandom8Test.class); 48 } 49 50 // max sampled int bound 51 static final int MAX_INT_BOUND = (1 << 26); 52 53 // max sampled long bound 54 static final long MAX_LONG_BOUND = (1L << 42); 55 56 // Number of replications for other checks 57 static final int REPS = 58 Integer.getInteger("ThreadLocalRandom8Test.reps", 4); 59 60 /** 61 * Invoking sized ints, long, doubles, with negative sizes throws 62 * IllegalArgumentException 63 */ 64 public void testBadStreamSize() { 65 ThreadLocalRandom r = ThreadLocalRandom.current(); 66 Runnable[] throwingActions = { 67 () -> r.ints(-1L), 68 () -> r.ints(-1L, 2, 3), 69 () -> r.longs(-1L), 70 () -> r.longs(-1L, -1L, 1L), 71 () -> r.doubles(-1L), 72 () -> r.doubles(-1L, .5, .6), 73 }; 74 assertThrows(IllegalArgumentException.class, throwingActions); 75 } 76 77 /** 78 * Invoking bounded ints, long, doubles, with illegal bounds throws 79 * IllegalArgumentException 80 */ 81 public void testBadStreamBounds() { 82 ThreadLocalRandom r = ThreadLocalRandom.current(); 83 Runnable[] throwingActions = { 84 () -> r.ints(2, 1), 85 () -> r.ints(10, 42, 42), 86 () -> r.longs(-1L, -1L), 87 () -> r.longs(10, 1L, -2L), 88 () -> r.doubles(0.0, 0.0), 89 () -> r.doubles(10, .5, .4), 90 }; 91 assertThrows(IllegalArgumentException.class, throwingActions); 92 } 93 94 /** 95 * A parallel sized stream of ints generates the given number of values 96 */ 97 public void testIntsCount() { 98 LongAdder counter = new LongAdder(); 99 ThreadLocalRandom r = ThreadLocalRandom.current(); 100 long size = 0; 101 for (int reps = 0; reps < REPS; ++reps) { 102 counter.reset(); 103 r.ints(size).parallel().forEach(x -> counter.increment()); 104 assertEquals(size, counter.sum()); 105 size += 524959; 106 } 107 } 108 109 /** 110 * A parallel sized stream of longs generates the given number of values 111 */ 112 public void testLongsCount() { 113 LongAdder counter = new LongAdder(); 114 ThreadLocalRandom r = ThreadLocalRandom.current(); 115 long size = 0; 116 for (int reps = 0; reps < REPS; ++reps) { 117 counter.reset(); 118 r.longs(size).parallel().forEach(x -> counter.increment()); 119 assertEquals(size, counter.sum()); 120 size += 524959; 121 } 122 } 123 124 /** 125 * A parallel sized stream of doubles generates the given number of values 126 */ 127 public void testDoublesCount() { 128 LongAdder counter = new LongAdder(); 129 ThreadLocalRandom r = ThreadLocalRandom.current(); 130 long size = 0; 131 for (int reps = 0; reps < REPS; ++reps) { 132 counter.reset(); 133 r.doubles(size).parallel().forEach(x -> counter.increment()); 134 assertEquals(size, counter.sum()); 135 size += 524959; 136 } 137 } 138 139 /** 140 * Each of a parallel sized stream of bounded ints is within bounds 141 */ 142 public void testBoundedInts() { 143 AtomicInteger fails = new AtomicInteger(0); 144 ThreadLocalRandom r = ThreadLocalRandom.current(); 145 long size = 12345L; 146 for (int least = -15485867; least < MAX_INT_BOUND; least += 524959) { 147 for (int bound = least + 2; bound > least && bound < MAX_INT_BOUND; bound += 67867967) { 148 final int lo = least, hi = bound; 149 r.ints(size, lo, hi).parallel().forEach( 150 x -> { 151 if (x < lo || x >= hi) 152 fails.getAndIncrement(); }); 153 } 154 } 155 assertEquals(0, fails.get()); 156 } 157 158 /** 159 * Each of a parallel sized stream of bounded longs is within bounds 160 */ 161 public void testBoundedLongs() { 162 AtomicInteger fails = new AtomicInteger(0); 163 ThreadLocalRandom r = ThreadLocalRandom.current(); 164 long size = 123L; 165 for (long least = -86028121; least < MAX_LONG_BOUND; least += 1982451653L) { 166 for (long bound = least + 2; bound > least && bound < MAX_LONG_BOUND; bound += Math.abs(bound * 7919)) { 167 final long lo = least, hi = bound; 168 r.longs(size, lo, hi).parallel().forEach( 169 x -> { 170 if (x < lo || x >= hi) 171 fails.getAndIncrement(); }); 172 } 173 } 174 assertEquals(0, fails.get()); 175 } 176 177 /** 178 * Each of a parallel sized stream of bounded doubles is within bounds 179 */ 180 public void testBoundedDoubles() { 181 AtomicInteger fails = new AtomicInteger(0); 182 ThreadLocalRandom r = ThreadLocalRandom.current(); 183 long size = 456; 184 for (double least = 0.00011; least < 1.0e20; least *= 9) { 185 for (double bound = least * 1.0011; bound < 1.0e20; bound *= 17) { 186 final double lo = least, hi = bound; 187 r.doubles(size, lo, hi).parallel().forEach( 188 x -> { 189 if (x < lo || x >= hi) 190 fails.getAndIncrement(); }); 191 } 192 } 193 assertEquals(0, fails.get()); 194 } 195 196 /** 197 * A parallel unsized stream of ints generates at least 100 values 198 */ 199 public void testUnsizedIntsCount() { 200 LongAdder counter = new LongAdder(); 201 ThreadLocalRandom r = ThreadLocalRandom.current(); 202 long size = 100; 203 r.ints().limit(size).parallel().forEach(x -> counter.increment()); 204 assertEquals(size, counter.sum()); 205 } 206 207 /** 208 * A parallel unsized stream of longs generates at least 100 values 209 */ 210 public void testUnsizedLongsCount() { 211 LongAdder counter = new LongAdder(); 212 ThreadLocalRandom r = ThreadLocalRandom.current(); 213 long size = 100; 214 r.longs().limit(size).parallel().forEach(x -> counter.increment()); 215 assertEquals(size, counter.sum()); 216 } 217 218 /** 219 * A parallel unsized stream of doubles generates at least 100 values 220 */ 221 public void testUnsizedDoublesCount() { 222 LongAdder counter = new LongAdder(); 223 ThreadLocalRandom r = ThreadLocalRandom.current(); 224 long size = 100; 225 r.doubles().limit(size).parallel().forEach(x -> counter.increment()); 226 assertEquals(size, counter.sum()); 227 } 228 229 /** 230 * A sequential unsized stream of ints generates at least 100 values 231 */ 232 public void testUnsizedIntsCountSeq() { 233 LongAdder counter = new LongAdder(); 234 ThreadLocalRandom r = ThreadLocalRandom.current(); 235 long size = 100; 236 r.ints().limit(size).forEach(x -> counter.increment()); 237 assertEquals(size, counter.sum()); 238 } 239 240 /** 241 * A sequential unsized stream of longs generates at least 100 values 242 */ 243 public void testUnsizedLongsCountSeq() { 244 LongAdder counter = new LongAdder(); 245 ThreadLocalRandom r = ThreadLocalRandom.current(); 246 long size = 100; 247 r.longs().limit(size).forEach(x -> counter.increment()); 248 assertEquals(size, counter.sum()); 249 } 250 251 /** 252 * A sequential unsized stream of doubles generates at least 100 values 253 */ 254 public void testUnsizedDoublesCountSeq() { 255 LongAdder counter = new LongAdder(); 256 ThreadLocalRandom r = ThreadLocalRandom.current(); 257 long size = 100; 258 r.doubles().limit(size).forEach(x -> counter.increment()); 259 assertEquals(size, counter.sum()); 260 } 261 262 /** 263 * A deserialized/reserialized ThreadLocalRandom is always 264 * identical to ThreadLocalRandom.current() 265 */ 266 public void testSerialization() { 267 assertSame( 268 ThreadLocalRandom.current(), 269 serialClone(ThreadLocalRandom.current())); 270 // In the current implementation, there is exactly one shared instance 271 if (testImplementationDetails) 272 assertSame( 273 ThreadLocalRandom.current(), 274 java.util.concurrent.CompletableFuture.supplyAsync( 275 () -> serialClone(ThreadLocalRandom.current())).join()); 276 } 277 278} 279