1 /*
2 * This file is part of Waarp Project (named also Waarp or GG).
3 *
4 * Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
5 * tags. See the COPYRIGHT.txt in the distribution for a full listing of
6 * individual contributors.
7 *
8 * All Waarp Project is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * Waarp . If not, see <http://www.gnu.org/licenses/>.
19 */
20 package org.waarp.common.utility;
21
22 /*
23 * Written by Doug Lea with assistance from members of JCP JSR-166
24 * Expert Group and released to the public domain, as explained at
25 * http://creativecommons.org/licenses/publicdomain
26 */
27
28 import java.util.Random;
29
30 /**
31 * A random number generator isolated to the current thread. Like the global
32 * {@link Random} generator used by
33 * the {@link Math} class, a {@code ThreadLocalRandom} is initialized with an
34 * internally generated seed that
35 * may not otherwise be modified. When applicable, use of {@code
36 * ThreadLocalRandom} rather than shared
37 * {@code Random} objects in concurrent programs will typically encounter much
38 * less overhead and contention.
39 * Use of {@code ThreadLocalRandom} is particularly appropriate when multiple
40 * tasks use random numbers in
41 * parallel in thread pools.
42 *
43 * <p>
44 * Usages of this class should typically be of the form: {@code
45 * ThreadLocalRandom.current().nextX(...)} (where
46 * {@code X} is {@code Int}, {@code Long}, etc). When all usages are of this
47 * form, it is never possible to
48 * accidently share a {@code ThreadLocalRandom} across multiple threads.
49 *
50 * <p>
51 * This class also provides additional commonly used bounded random generation
52 * methods.
53 *
54 * @since 1.7
55 */
56 public final class ThreadLocalRandom extends Random {
57 // same constants as Random, but must be redeclared because private
58 private static final long MULTIPLIER = 0x5DEECE66DL;
59 private static final long ADDEND = 0xBL;
60 private static final long MASK = (1L << 48) - 1;
61
62 /**
63 * The random seed. We can't use super.seed.
64 */
65 private long rnd;
66
67 /**
68 * Initialization flag to permit the first and only allowed call to setSeed
69 * (inside Random constructor) to
70 * succeed. We can't allow others since it would cause setting seed in one
71 * part of a program to
72 * unintentionally impact other usages by the thread.
73 */
74 private boolean initialized;
75
76 /**
77 * The actual ThreadLocal
78 */
79 private static final ThreadLocal<ThreadLocalRandom> localRandom =//NOSONAR
80 new ThreadLocal<ThreadLocalRandom>() {
81 @Override
82 protected final ThreadLocalRandom initialValue() {
83 return new ThreadLocalRandom();
84 }
85 };//NOSONAR
86
87 /**
88 * Returns the current thread's {@code ThreadLocalRandom}.
89 *
90 * @return the current thread's {@code ThreadLocalRandom}
91 */
92 public static ThreadLocalRandom current() {
93 return localRandom.get();
94 }
95
96 /**
97 * Throws {@code UnsupportedOperationException}. Setting seeds in this
98 * generator is not supported.
99 *
100 * @throws UnsupportedOperationException always
101 */
102 @Override
103 public final void setSeed(final long seed) {//NOSONAR
104 // We rely on the fact that the superclass no-arg constructor
105 // invokes setSeed exactly once to initialize.
106 if (initialized) {
107 throw new UnsupportedOperationException();
108 }
109 initialized = true;
110 rnd = (seed ^ MULTIPLIER) & MASK;
111 }
112
113 @Override
114 protected final int next(final int bits) {
115 rnd = rnd * MULTIPLIER + ADDEND & MASK;
116 return (int) (rnd >>> 48 - bits);
117 }
118
119 private static final long serialVersionUID = -5851777807851030925L;
120 }