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 7 package java.util.concurrent; 8 9 import java.util.Random; 10 11 /** 12 * A random number generator isolated to the current thread. Like the 13 * global {@link java.util.Random} generator used by the {@link 14 * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized 15 * with an internally generated seed that may not otherwise be 16 * modified. When applicable, use of {@code ThreadLocalRandom} rather 17 * than shared {@code Random} objects in concurrent programs will 18 * typically encounter much less overhead and contention. Use of 19 * {@code ThreadLocalRandom} is particularly appropriate when multiple 20 * tasks (for example, each a {@link ForkJoinTask}) use random numbers 21 * in parallel in thread pools. 22 * 23 * <p>Usages of this class should typically be of the form: 24 * {@code ThreadLocalRandom.current().nextX(...)} (where 25 * {@code X} is {@code Int}, {@code Long}, etc). 26 * When all usages are of this form, it is never possible to 27 * accidently share a {@code ThreadLocalRandom} across multiple threads. 28 * 29 * <p>This class also provides additional commonly used bounded random 30 * generation methods. 31 * 32 * @since 1.7 33 * @author Doug Lea 34 */ 35 public class ThreadLocalRandom extends Random { 36 // same constants as Random, but must be redeclared because private 37 private static final long multiplier = 0x5DEECE66DL; 38 private static final long addend = 0xBL; 39 private static final long mask = (1L << 48) - 1; 40 41 /** 42 * The random seed. We can't use super.seed. 43 */ 44 private long rnd; 45 46 /** 47 * Initialization flag to permit calls to setSeed to succeed only 48 * while executing the Random constructor. We can't allow others 49 * since it would cause setting seed in one part of a program to 50 * unintentionally impact other usages by the thread. 51 */ 52 boolean initialized; 53 54 // Padding to help avoid memory contention among seed updates in 55 // different TLRs in the common case that they are located near 56 // each other. 57 private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7; 58 59 /** 60 * The actual ThreadLocal 61 */ 62 private static final ThreadLocal<ThreadLocalRandom> localRandom = 63 new ThreadLocal<ThreadLocalRandom>() { 64 protected ThreadLocalRandom initialValue() { 65 return new ThreadLocalRandom(); 66 } 67 }; 68 69 70 /** 71 * Constructor called only by localRandom.initialValue. 72 */ ThreadLocalRandom()73 ThreadLocalRandom() { 74 super(); 75 initialized = true; 76 } 77 78 /** 79 * Returns the current thread's {@code ThreadLocalRandom}. 80 * 81 * @return the current thread's {@code ThreadLocalRandom} 82 */ current()83 public static ThreadLocalRandom current() { 84 return localRandom.get(); 85 } 86 87 /** 88 * Throws {@code UnsupportedOperationException}. Setting seeds in 89 * this generator is not supported. 90 * 91 * @throws UnsupportedOperationException always 92 */ setSeed(long seed)93 public void setSeed(long seed) { 94 if (initialized) 95 throw new UnsupportedOperationException(); 96 rnd = (seed ^ multiplier) & mask; 97 } 98 next(int bits)99 protected int next(int bits) { 100 rnd = (rnd * multiplier + addend) & mask; 101 return (int) (rnd >>> (48-bits)); 102 } 103 104 /** 105 * Returns a pseudorandom, uniformly distributed value between the 106 * given least value (inclusive) and bound (exclusive). 107 * 108 * @param least the least value returned 109 * @param bound the upper bound (exclusive) 110 * @throws IllegalArgumentException if least greater than or equal 111 * to bound 112 * @return the next value 113 */ nextInt(int least, int bound)114 public int nextInt(int least, int bound) { 115 if (least >= bound) 116 throw new IllegalArgumentException(); 117 return nextInt(bound - least) + least; 118 } 119 120 /** 121 * Returns a pseudorandom, uniformly distributed value 122 * between 0 (inclusive) and the specified value (exclusive). 123 * 124 * @param n the bound on the random number to be returned. Must be 125 * positive. 126 * @return the next value 127 * @throws IllegalArgumentException if n is not positive 128 */ nextLong(long n)129 public long nextLong(long n) { 130 if (n <= 0) 131 throw new IllegalArgumentException("n must be positive"); 132 // Divide n by two until small enough for nextInt. On each 133 // iteration (at most 31 of them but usually much less), 134 // randomly choose both whether to include high bit in result 135 // (offset) and whether to continue with the lower vs upper 136 // half (which makes a difference only if odd). 137 long offset = 0; 138 while (n >= Integer.MAX_VALUE) { 139 int bits = next(2); 140 long half = n >>> 1; 141 long nextn = ((bits & 2) == 0) ? half : n - half; 142 if ((bits & 1) == 0) 143 offset += n - nextn; 144 n = nextn; 145 } 146 return offset + nextInt((int) n); 147 } 148 149 /** 150 * Returns a pseudorandom, uniformly distributed value between the 151 * given least value (inclusive) and bound (exclusive). 152 * 153 * @param least the least value returned 154 * @param bound the upper bound (exclusive) 155 * @return the next value 156 * @throws IllegalArgumentException if least greater than or equal 157 * to bound 158 */ nextLong(long least, long bound)159 public long nextLong(long least, long bound) { 160 if (least >= bound) 161 throw new IllegalArgumentException(); 162 return nextLong(bound - least) + least; 163 } 164 165 /** 166 * Returns a pseudorandom, uniformly distributed {@code double} value 167 * between 0 (inclusive) and the specified value (exclusive). 168 * 169 * @param n the bound on the random number to be returned. Must be 170 * positive. 171 * @return the next value 172 * @throws IllegalArgumentException if n is not positive 173 */ nextDouble(double n)174 public double nextDouble(double n) { 175 if (n <= 0) 176 throw new IllegalArgumentException("n must be positive"); 177 return nextDouble() * n; 178 } 179 180 /** 181 * Returns a pseudorandom, uniformly distributed value between the 182 * given least value (inclusive) and bound (exclusive). 183 * 184 * @param least the least value returned 185 * @param bound the upper bound (exclusive) 186 * @return the next value 187 * @throws IllegalArgumentException if least greater than or equal 188 * to bound 189 */ nextDouble(double least, double bound)190 public double nextDouble(double least, double bound) { 191 if (least >= bound) 192 throw new IllegalArgumentException(); 193 return nextDouble() * (bound - least) + least; 194 } 195 196 private static final long serialVersionUID = -5851777807851030925L; 197 } 198