简介

  • 随机数字生成器
  • 生成的是伪随机数

    源码

    1. public class Random implements java.io.Serializable {
    2. static final long serialVersionUID = 3905348978240129619L;
    3. // 此处是一个 原子类 AtomicLong 种子
    4. private final AtomicLong seed;
    5. // 乘数
    6. private static final long multiplier = 0x5DEECE66DL;
    7. // 加数
    8. private static final long addend = 0xBL;
    9. //
    10. private static final long mask = (1L << 48) - 1;
    11. private static final double DOUBLE_UNIT = 0x1.0p-53; // 1.0 / (1L << 53)
    12. // IllegalArgumentException消息
    13. static final String BadBound = "bound must be positive";
    14. static final String BadRange = "bound must be greater than origin";
    15. static final String BadSize = "size must be non-negative";
    16. // 无参构造器 调用另一个有参构造器
    17. public Random() {
    18. this(seedUniquifier() ^ System.nanoTime());
    19. }
    20. // 种子统一符方法
    21. private static long seedUniquifier() {
    22. for (;;) {
    23. long current = seedUniquifier.get();
    24. long next = current * 181783497276652981L;
    25. if (seedUniquifier.compareAndSet(current, next))
    26. return next;
    27. }
    28. }
    29. // 种子统一数据
    30. private static final AtomicLong seedUniquifier
    31. = new AtomicLong(8682522807148012L);
    32. // 参数为种子长度的构造方法
    33. public Random(long seed) {
    34. if (getClass() == Random.class)
    35. this.seed = new AtomicLong(initialScramble(seed));
    36. else {
    37. this.seed = new AtomicLong();
    38. setSeed(seed);
    39. }
    40. }
    41. private static long initialScramble(long seed) {
    42. return (seed ^ multiplier) & mask;
    43. }
    44. // 设置此随机数生成器的使用单个种子long的种子。
    45. // 总承包setSeed是,它改变了这个随机数生成器对象的状态,
    46. // 从而,如果它刚刚与参数创建是完全相同的状态seed的种子。
    47. // 该方法setSeed由类实现Random通过原子地更新所述种子
    48. // (seed ^ 0x5DEECE66DL) & ((1L << 48) - 1) 并清除haveNextNextGaussian由已使用标记
    49. synchronized public void setSeed(long seed) {
    50. this.seed.set(initialScramble(seed));
    51. haveNextNextGaussian = false;
    52. }
    53. // 产生一个伪随机数。 子类应覆盖这一点,因为这是使用的所有其他方法。
    54. protected int next(int bits) {
    55. long oldseed, nextseed;
    56. AtomicLong seed = this.seed;
    57. do {
    58. oldseed = seed.get();
    59. nextseed = (oldseed * multiplier + addend) & mask;
    60. } while (!seed.compareAndSet(oldseed, nextseed));
    61. return (int)(nextseed >>> (48 - bits));
    62. }
    63. // 生成随机字节并将它们放置到用户提供的字节数组。 产生的随机字节数等于字节数组的长度
    64. public void nextBytes(byte[] bytes) {
    65. for (int i = 0, len = bytes.length; i < len; )
    66. for (int rnd = nextInt(),
    67. n = Math.min(len - i, Integer.SIZE/Byte.SIZE);
    68. n-- > 0; rnd >>= Byte.SIZE)
    69. bytes[i++] = (byte)rnd;
    70. }
    71. // nextLong的形式使用通过LongStream Spliterators。
    72. // 如果原产地是大于约束,作为nextLong的无限形式,否则为界形式
    73. final long internalNextLong(long origin, long bound) {
    74. long r = nextLong();
    75. if (origin < bound) {
    76. long n = bound - origin, m = n - 1;
    77. if ((n & m) == 0L) // power of two
    78. r = (r & m) + origin;
    79. else if (n > 0L) { // reject over-represented candidates
    80. for (long u = r >>> 1; // ensure nonnegative
    81. u + m - (r = u % n) < 0L; // rejection check
    82. u = nextLong() >>> 1) // retry
    83. ;
    84. r += origin;
    85. }
    86. else { // range not representable as long
    87. while (r < origin || r >= bound)
    88. r = nextLong();
    89. }
    90. }
    91. return r;
    92. }
    93. // 返回伪随机值
    94. final int internalNextInt(int origin, int bound) {
    95. if (origin < bound) {
    96. int n = bound - origin;
    97. if (n > 0) {
    98. return nextInt(n) + origin;
    99. }
    100. else { // range not representable as int
    101. int r;
    102. do {
    103. r = nextInt();
    104. } while (r < origin || r >= bound);
    105. return r;
    106. }
    107. }
    108. else {
    109. return nextInt();
    110. }
    111. }
    112. // 返回伪随机值
    113. final double internalNextDouble(double origin, double bound) {
    114. double r = nextDouble();
    115. if (origin < bound) {
    116. r = r * (bound - origin) + origin;
    117. if (r >= bound) // correct for rounding
    118. r = Double.longBitsToDouble(Double.doubleToLongBits(bound) - 1);
    119. }
    120. return r;
    121. }
    122. // 无参数的nextInt方法
    123. public int nextInt() {
    124. return next(32);
    125. }
    126. // 带有参数的 nextInt 方法,参数为界限
    127. public int nextInt(int bound) {
    128. if (bound <= 0)
    129. throw new IllegalArgumentException(BadBound);
    130. int r = next(31);
    131. int m = bound - 1;
    132. if ((bound & m) == 0) // i.e., bound is a power of 2
    133. r = (int)((bound * (long)r) >> 31);
    134. else {
    135. for (int u = r;
    136. u - (r = u % bound) + m < 0;
    137. u = next(31))
    138. ;
    139. }
    140. return r;
    141. }
    142. // 返回下一个伪,均匀分布的long从该随机数生成器的序列值。
    143. // 总承包nextLong是一个long值伪随机地生成并返回
    144. public long nextLong() {
    145. // it's okay that the bottom word remains signed.
    146. return ((long)(next(32)) << 32) + next(32);
    147. }
    148. // 返回均匀分布的boolean值
    149. public boolean nextBoolean() {
    150. return next(1) != 0;
    151. }
    152. // 返回均匀分布的 ,在[0.0,1.0)之间的float数
    153. public float nextFloat() {
    154. return next(24) / ((float)(1 << 24));
    155. }
    156. // 返回均匀分布的 ,在[0.0,1.0)之间的double数
    157. public double nextDouble() {
    158. return (((long)(next(26)) << 27) + next(27)) * DOUBLE_UNIT;
    159. }
    160. private double nextNextGaussian;
    161. private boolean haveNextNextGaussian = false;
    162. // 返回下一个伪高斯(“正常”)分布的double用平均值0.0和标准偏差1.0从该随机数生成器的序列。
    163. synchronized public double nextGaussian() {
    164. // See Knuth, ACP, Section 3.4.1 Algorithm C.
    165. if (haveNextNextGaussian) {
    166. haveNextNextGaussian = false;
    167. return nextNextGaussian;
    168. } else {
    169. double v1, v2, s;
    170. do {
    171. v1 = 2 * nextDouble() - 1; // between -1 and 1
    172. v2 = 2 * nextDouble() - 1; // between -1 and 1
    173. s = v1 * v1 + v2 * v2;
    174. } while (s >= 1 || s == 0);
    175. double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);
    176. nextNextGaussian = v2 * multiplier;
    177. haveNextNextGaussian = true;
    178. return v1 * multiplier;
    179. }
    180. }
    181. // 返回产生所述给定流streamSize伪随机数int值。
    182. // 伪随机int ,如果是在调用该方法的结果生成的值nextInt()
    183. public IntStream ints(long streamSize) {
    184. if (streamSize < 0L)
    185. throw new IllegalArgumentException(BadSize);
    186. return StreamSupport.intStream
    187. (new RandomIntsSpliterator
    188. (this, 0L, streamSize, Integer.MAX_VALUE, 0),
    189. false);
    190. }
    191. public IntStream ints() {
    192. return StreamSupport.intStream
    193. (new RandomIntsSpliterator
    194. (this, 0L, Long.MAX_VALUE, Integer.MAX_VALUE, 0),
    195. false);
    196. }
    197. public IntStream ints(long streamSize, int randomNumberOrigin,
    198. int randomNumberBound) {
    199. if (streamSize < 0L)
    200. throw new IllegalArgumentException(BadSize);
    201. if (randomNumberOrigin >= randomNumberBound)
    202. throw new IllegalArgumentException(BadRange);
    203. return StreamSupport.intStream
    204. (new RandomIntsSpliterator
    205. (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
    206. false);
    207. }
    208. public IntStream ints(int randomNumberOrigin, int randomNumberBound) {
    209. if (randomNumberOrigin >= randomNumberBound)
    210. throw new IllegalArgumentException(BadRange);
    211. return StreamSupport.intStream
    212. (new RandomIntsSpliterator
    213. (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
    214. false);
    215. }
    216. // 返回生产给定流streamSize伪随机数long值
    217. public LongStream longs(long streamSize) {
    218. if (streamSize < 0L)
    219. throw new IllegalArgumentException(BadSize);
    220. return StreamSupport.longStream
    221. (new RandomLongsSpliterator
    222. (this, 0L, streamSize, Long.MAX_VALUE, 0L),
    223. false);
    224. }
    225. public LongStream longs() {
    226. return StreamSupport.longStream
    227. (new RandomLongsSpliterator
    228. (this, 0L, Long.MAX_VALUE, Long.MAX_VALUE, 0L),
    229. false);
    230. }
    231. public LongStream longs(long streamSize, long randomNumberOrigin,
    232. long randomNumberBound) {
    233. if (streamSize < 0L)
    234. throw new IllegalArgumentException(BadSize);
    235. if (randomNumberOrigin >= randomNumberBound)
    236. throw new IllegalArgumentException(BadRange);
    237. return StreamSupport.longStream
    238. (new RandomLongsSpliterator
    239. (this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
    240. false);
    241. }
    242. public LongStream longs(long randomNumberOrigin, long randomNumberBound) {
    243. if (randomNumberOrigin >= randomNumberBound)
    244. throw new IllegalArgumentException(BadRange);
    245. return StreamSupport.longStream
    246. (new RandomLongsSpliterator
    247. (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
    248. false);
    249. }
    250. public DoubleStream doubles(long streamSize) {
    251. if (streamSize < 0L)
    252. throw new IllegalArgumentException(BadSize);
    253. return StreamSupport.doubleStream
    254. (new RandomDoublesSpliterator
    255. (this, 0L, streamSize, Double.MAX_VALUE, 0.0),
    256. false);
    257. }
    258. public DoubleStream doubles() {
    259. return StreamSupport.doubleStream
    260. (new RandomDoublesSpliterator
    261. (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
    262. false);
    263. }
    264. public DoubleStream doubles() {
    265. return StreamSupport.doubleStream
    266. (new RandomDoublesSpliterator
    267. (this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
    268. false);
    269. }
    270. public DoubleStream doubles(double randomNumberOrigin, double randomNumberBound) {
    271. if (!(randomNumberOrigin < randomNumberBound))
    272. throw new IllegalArgumentException(BadRange);
    273. return StreamSupport.doubleStream
    274. (new RandomDoublesSpliterator
    275. (this, 0L, Long.MAX_VALUE, randomNumberOrigin, randomNumberBound),
    276. false);
    277. }
    278. // 静态内部类 分流器
    279. static final class RandomIntsSpliterator implements Spliterator.OfInt {
    280. final Random rng;
    281. long index;
    282. final long fence;
    283. final int origin;
    284. final int bound;
    285. RandomIntsSpliterator(Random rng, long index, long fence,
    286. int origin, int bound) {
    287. this.rng = rng; this.index = index; this.fence = fence;
    288. this.origin = origin; this.bound = bound;
    289. }
    290. public RandomIntsSpliterator trySplit() {
    291. long i = index, m = (i + fence) >>> 1;
    292. return (m <= i) ? null :
    293. new RandomIntsSpliterator(rng, i, index = m, origin, bound);
    294. }
    295. public long estimateSize() {
    296. return fence - index;
    297. }
    298. public int characteristics() {
    299. return (Spliterator.SIZED | Spliterator.SUBSIZED |
    300. Spliterator.NONNULL | Spliterator.IMMUTABLE);
    301. }
    302. public boolean tryAdvance(IntConsumer consumer) {
    303. if (consumer == null) throw new NullPointerException();
    304. long i = index, f = fence;
    305. if (i < f) {
    306. consumer.accept(rng.internalNextInt(origin, bound));
    307. index = i + 1;
    308. return true;
    309. }
    310. return false;
    311. }
    312. public void forEachRemaining(IntConsumer consumer) {
    313. if (consumer == null) throw new NullPointerException();
    314. long i = index, f = fence;
    315. if (i < f) {
    316. index = f;
    317. Random r = rng;
    318. int o = origin, b = bound;
    319. do {
    320. consumer.accept(r.internalNextInt(o, b));
    321. } while (++i < f);
    322. }
    323. }
    324. }
    325. // 分词器
    326. static final class RandomLongsSpliterator implements Spliterator.OfLong {
    327. final Random rng;
    328. long index;
    329. final long fence;
    330. final long origin;
    331. final long bound;
    332. RandomLongsSpliterator(Random rng, long index, long fence,
    333. long origin, long bound) {
    334. this.rng = rng; this.index = index; this.fence = fence;
    335. this.origin = origin; this.bound = bound;
    336. }
    337. public RandomLongsSpliterator trySplit() {
    338. long i = index, m = (i + fence) >>> 1;
    339. return (m <= i) ? null :
    340. new RandomLongsSpliterator(rng, i, index = m, origin, bound);
    341. }
    342. public long estimateSize() {
    343. return fence - index;
    344. }
    345. public int characteristics() {
    346. return (Spliterator.SIZED | Spliterator.SUBSIZED |
    347. Spliterator.NONNULL | Spliterator.IMMUTABLE);
    348. }
    349. public boolean tryAdvance(LongConsumer consumer) {
    350. if (consumer == null) throw new NullPointerException();
    351. long i = index, f = fence;
    352. if (i < f) {
    353. consumer.accept(rng.internalNextLong(origin, bound));
    354. index = i + 1;
    355. return true;
    356. }
    357. return false;
    358. }
    359. public void forEachRemaining(LongConsumer consumer) {
    360. if (consumer == null) throw new NullPointerException();
    361. long i = index, f = fence;
    362. if (i < f) {
    363. index = f;
    364. Random r = rng;
    365. long o = origin, b = bound;
    366. do {
    367. consumer.accept(r.internalNextLong(o, b));
    368. } while (++i < f);
    369. }
    370. }
    371. }
    372. // 分词器
    373. static final class RandomLongsSpliterator implements Spliterator.OfLong {
    374. final Random rng;
    375. long index;
    376. final long fence;
    377. final long origin;
    378. final long bound;
    379. RandomLongsSpliterator(Random rng, long index, long fence,
    380. long origin, long bound) {
    381. this.rng = rng; this.index = index; this.fence = fence;
    382. this.origin = origin; this.bound = bound;
    383. }
    384. public RandomLongsSpliterator trySplit() {
    385. long i = index, m = (i + fence) >>> 1;
    386. return (m <= i) ? null :
    387. new RandomLongsSpliterator(rng, i, index = m, origin, bound);
    388. }
    389. public long estimateSize() {
    390. return fence - index;
    391. }
    392. public int characteristics() {
    393. return (Spliterator.SIZED | Spliterator.SUBSIZED |
    394. Spliterator.NONNULL | Spliterator.IMMUTABLE);
    395. }
    396. public boolean tryAdvance(LongConsumer consumer) {
    397. if (consumer == null) throw new NullPointerException();
    398. long i = index, f = fence;
    399. if (i < f) {
    400. consumer.accept(rng.internalNextLong(origin, bound));
    401. index = i + 1;
    402. return true;
    403. }
    404. return false;
    405. }
    406. public void forEachRemaining(LongConsumer consumer) {
    407. if (consumer == null) throw new NullPointerException();
    408. long i = index, f = fence;
    409. if (i < f) {
    410. index = f;
    411. Random r = rng;
    412. long o = origin, b = bound;
    413. do {
    414. consumer.accept(r.internalNextLong(o, b));
    415. } while (++i < f);
    416. }
    417. }
    418. }
    419. //
    420. static final class RandomDoublesSpliterator implements Spliterator.OfDouble {
    421. final Random rng;
    422. long index;
    423. final long fence;
    424. final double origin;
    425. final double bound;
    426. RandomDoublesSpliterator(Random rng, long index, long fence,
    427. double origin, double bound) {
    428. this.rng = rng; this.index = index; this.fence = fence;
    429. this.origin = origin; this.bound = bound;
    430. }
    431. public RandomDoublesSpliterator trySplit() {
    432. long i = index, m = (i + fence) >>> 1;
    433. return (m <= i) ? null :
    434. new RandomDoublesSpliterator(rng, i, index = m, origin, bound);
    435. }
    436. public long estimateSize() {
    437. return fence - index;
    438. }
    439. public int characteristics() {
    440. return (Spliterator.SIZED | Spliterator.SUBSIZED |
    441. Spliterator.NONNULL | Spliterator.IMMUTABLE);
    442. }
    443. public boolean tryAdvance(DoubleConsumer consumer) {
    444. if (consumer == null) throw new NullPointerException();
    445. long i = index, f = fence;
    446. if (i < f) {
    447. consumer.accept(rng.internalNextDouble(origin, bound));
    448. index = i + 1;
    449. return true;
    450. }
    451. return false;
    452. }
    453. public void forEachRemaining(DoubleConsumer consumer) {
    454. if (consumer == null) throw new NullPointerException();
    455. long i = index, f = fence;
    456. if (i < f) {
    457. index = f;
    458. Random r = rng;
    459. double o = origin, b = bound;
    460. do {
    461. consumer.accept(r.internalNextDouble(o, b));
    462. } while (++i < f);
    463. }
    464. }
    465. }
    466. private static final ObjectStreamField[] serialPersistentFields = {
    467. new ObjectStreamField("seed", Long.TYPE),
    468. new ObjectStreamField("nextNextGaussian", Double.TYPE),
    469. new ObjectStreamField("haveNextNextGaussian", Boolean.TYPE)
    470. };
    471. private void readObject(java.io.ObjectInputStream s)
    472. throws java.io.IOException, ClassNotFoundException {
    473. ObjectInputStream.GetField fields = s.readFields();
    474. long seedVal = fields.get("seed", -1L);
    475. if (seedVal < 0)
    476. throw new java.io.StreamCorruptedException(
    477. "Random: invalid seed");
    478. resetSeed(seedVal);
    479. nextNextGaussian = fields.get("nextNextGaussian", 0.0);
    480. haveNextNextGaussian = fields.get("haveNextNextGaussian", false);
    481. }
    482. synchronized private void writeObject(ObjectOutputStream s)
    483. throws IOException {
    484. // set the values of the Serializable fields
    485. ObjectOutputStream.PutField fields = s.putFields();
    486. // The seed is serialized as a long for historical reasons.
    487. fields.put("seed", seed.get());
    488. fields.put("nextNextGaussian", nextNextGaussian);
    489. fields.put("haveNextNextGaussian", haveNextNextGaussian);
    490. // save them
    491. s.writeFields();
    492. }
    493. private static final Unsafe unsafe = Unsafe.getUnsafe();
    494. private static final long seedOffset;
    495. static {
    496. try {
    497. seedOffset = unsafe.objectFieldOffset
    498. (Random.class.getDeclaredField("seed"));
    499. } catch (Exception ex) { throw new Error(ex); }
    500. }
    501. private void resetSeed(long seedVal) {
    502. unsafe.putObjectVolatile(this, seedOffset, new AtomicLong(seedVal));
    503. }
    504. }

    伪随机数

    public class RandomTest {
      public static void main(String[] args) {
          //只要两个Random对象的种子相同,而且方法的调用顺序也相同,产生的随机数相同         
          //Random产生的数字并不是真正随机的,而是一种伪随机         
          Random r1 = new Random(16);
          System.out.println("第一个种子为16的Random对象");
          System.out.println("r1.nextBoolean() =  " + r1.nextBoolean());
          System.out.println("r1.nextInt() =      " + r1.nextInt());
          System.out.println("r1.nextDouble() =   " + r1.nextDouble());
          System.out.println("r1.nextGaussian() = " + r1.nextGaussian());
          System.out.println("-------------------------------------------------------");
      }
    }
    
  • 多次的执行结果如下 ```java 第一个种子为16的Random对象 r1.nextBoolean() = true r1.nextInt() = -2031839431 r1.nextDouble() = 0.527826082540034 r1.nextGaussian() = 0.014363412537037566


```

  • 因为其执行的结果都一样,所以称之为伪随机数

    总结

  • 在上面的分析中,我没有过多的去解释代码的作用

  • Random中用到了 AtomicLong 类。最后返回 (int)(nextseed >>> (48 - bits))
  • 核心算法是next(int bits) 在其方法内部执行了CAS计算
  • 同时也用到了高斯分布