View Javadoc
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 }