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 }