ThreadLocalRandom.java

/*
 * This file is part of Waarp Project (named also Waarp or GG).
 *
 *  Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
 *  tags. See the COPYRIGHT.txt in the distribution for a full listing of
 * individual contributors.
 *
 *  All Waarp Project is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
 *
 * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along with
 * Waarp . If not, see <http://www.gnu.org/licenses/>.
 */
package org.waarp.common.utility;

/*
 * Written by Doug Lea with assistance from members of JCP JSR-166
 * Expert Group and released to the public domain, as explained at
 * http://creativecommons.org/licenses/publicdomain
 */

import java.util.Random;

/**
 * A random number generator isolated to the current thread. Like the global
 * {@link Random} generator used by
 * the {@link Math} class, a {@code ThreadLocalRandom} is initialized with an
 * internally generated seed that
 * may not otherwise be modified. When applicable, use of {@code
 * ThreadLocalRandom} rather than shared
 * {@code Random} objects in concurrent programs will typically encounter much
 * less overhead and contention.
 * Use of {@code ThreadLocalRandom} is particularly appropriate when multiple
 * tasks use random numbers in
 * parallel in thread pools.
 *
 * <p>
 * Usages of this class should typically be of the form: {@code
 * ThreadLocalRandom.current().nextX(...)} (where
 * {@code X} is {@code Int}, {@code Long}, etc). When all usages are of this
 * form, it is never possible to
 * accidently share a {@code ThreadLocalRandom} across multiple threads.
 *
 * <p>
 * This class also provides additional commonly used bounded random generation
 * methods.
 *
 * @since 1.7
 */
public final class ThreadLocalRandom extends Random {
  // same constants as Random, but must be redeclared because private
  private static final long MULTIPLIER = 0x5DEECE66DL;
  private static final long ADDEND = 0xBL;
  private static final long MASK = (1L << 48) - 1;

  /**
   * The random seed. We can't use super.seed.
   */
  private long rnd;

  /**
   * Initialization flag to permit the first and only allowed call to setSeed
   * (inside Random constructor) to
   * succeed. We can't allow others since it would cause setting seed in one
   * part of a program to
   * unintentionally impact other usages by the thread.
   */
  private boolean initialized;

  /**
   * The actual ThreadLocal
   */
  private static final ThreadLocal<ThreadLocalRandom> localRandom =//NOSONAR
      new ThreadLocal<ThreadLocalRandom>() {
        @Override
        protected final ThreadLocalRandom initialValue() {
          return new ThreadLocalRandom();
        }
      };//NOSONAR

  /**
   * Returns the current thread's {@code ThreadLocalRandom}.
   *
   * @return the current thread's {@code ThreadLocalRandom}
   */
  public static ThreadLocalRandom current() {
    return localRandom.get();
  }

  /**
   * Throws {@code UnsupportedOperationException}. Setting seeds in this
   * generator is not supported.
   *
   * @throws UnsupportedOperationException always
   */
  @Override
  public final void setSeed(final long seed) {//NOSONAR
    // We rely on the fact that the superclass no-arg constructor
    // invokes setSeed exactly once to initialize.
    if (initialized) {
      throw new UnsupportedOperationException();
    }
    initialized = true;
    rnd = (seed ^ MULTIPLIER) & MASK;
  }

  @Override
  protected final int next(final int bits) {
    rnd = rnd * MULTIPLIER + ADDEND & MASK;
    return (int) (rnd >>> 48 - bits);
  }

  private static final long serialVersionUID = -5851777807851030925L;
}