View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the License. You may obtain a copy of the License at:
    7    *
    8    *   http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16
    17  /*
    18   * Written by Doug Lea with assistance from members of JCP JSR-166
    19   * Expert Group and released to the public domain, as explained at
    20   * http://creativecommons.org/licenses/publicdomain
    21   */
    22
    23  package org.jboss.netty.util.internal;
    24
    25  import java.util.Random;
    26
    27  /**
    28   * A random number generator isolated to the current thread.  Like the
    29   * global {@link java.util.Random} generator used by the {@link
    30   * java.lang.Math} class, a {@code ThreadLocalRandom} is initialized
    31   * with an internally generated seed that may not otherwise be
    32   * modified. When applicable, use of {@code ThreadLocalRandom} rather
    33   * than shared {@code Random} objects in concurrent programs will
    34   * typically encounter much less overhead and contention.  Use of
    35   * {@code ThreadLocalRandom} is particularly appropriate when multiple
    36   * tasks use random numbers in parallel in thread pools.
    37   *
    38   * <p>Usages of this class should typically be of the form:
    39   * {@code ThreadLocalRandom.current().nextX(...)} (where
    40   * {@code X} is {@code Int}, {@code Long}, etc).
    41   * When all usages are of this form, it is never possible to
    42   * accidently share a {@code ThreadLocalRandom} across multiple threads.
    43   *
    44   * <p>This class also provides additional commonly used bounded random
    45   * generation methods.
    46   *
    47   * @since 1.7
    48   */
    49  final class ThreadLocalRandom extends Random {
    50      // same constants as Random, but must be redeclared because private
    51      private static final long multiplier = 0x5DEECE66DL;
    52      private static final long addend = 0xBL;
    53      private static final long mask = (1L << 48) - 1;
    54
    55      /**
    56       * The random seed. We can't use super.seed.
    57       */
    58      private long rnd;
    59
    60      /**
    61       * Initialization flag to permit the first and only allowed call
    62       * to setSeed (inside Random constructor) to succeed.  We can't
    63       * allow others since it would cause setting seed in one part of a
    64       * program to unintentionally impact other usages by the thread.
    65       */
    66      private boolean initialized;
    67
    68      // Padding to help avoid memory contention among seed updates in
    69      // different TLRs in the common case that they are located near
    70      // each other.
    71      @SuppressWarnings("unused")
    72      private long pad0, pad1, pad2, pad3, pad4, pad5, pad6, pad7;
    73
    74      /**
    75       * The actual ThreadLocal
    76       */
    77      private static final ThreadLocal<ThreadLocalRandom> localRandom =
    78          new ThreadLocal<ThreadLocalRandom>() {
    79              @Override
    80              protected ThreadLocalRandom initialValue() {
    81                  return new ThreadLocalRandom();
    82              }
    83      };
    84
    85
    86      /**
    87       * Constructor called only by localRandom.initialValue.
    88       * We rely on the fact that the superclass no-arg constructor
    89       * invokes setSeed exactly once to initialize.
    90       */
    91      ThreadLocalRandom() {
    92          super();
    93      }
    94
    95      /**
    96       * Returns the current thread's {@code ThreadLocalRandom}.
    97       *
    98       * @return the current thread's {@code ThreadLocalRandom}
    99       */
    100     static ThreadLocalRandom current() {
    101         return localRandom.get();
    102     }
    103
    104     /**
    105      * Throws {@code UnsupportedOperationException}.  Setting seeds in
    106      * this generator is not supported.
    107      *
    108      * @throws UnsupportedOperationException always
    109      */
    110     @Override
    111     public void setSeed(long seed) {
    112         if (initialized) {
    113             throw new UnsupportedOperationException();
    114         }
    115         initialized = true;
    116         rnd = (seed ^ multiplier) & mask;
    117     }
    118
    119     @Override
    120     protected int next(int bits) {
    121         rnd = rnd * multiplier + addend & mask;
    122         return (int) (rnd >>> 48 - bits);
    123     }
    124
    125     private static final long serialVersionUID = -5851777807851030925L;
    126 }