/* * Copyright 2015 MiLaboratory.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.milaboratory.util; import org.apache.commons.math3.random.RandomDataGenerator; import org.apache.commons.math3.random.Well19937c; import java.util.concurrent.atomic.AtomicLong; public final class RandomUtil { private RandomUtil() { } static final ThreadLocal<Randomm> threadLocalRandom = new ThreadLocal<Randomm>() { @Override protected Randomm initialValue() { //Generating thread-specific seed long seed = seedCounter.addAndGet(353L); seed = HashFunctions.JenkinWang64shift(seed); //Creating random generator return new Randomm(new Well19937c(seed)); } }; //Used to generate individual seeds for each thread-local random generator private static final AtomicLong seedCounter = new AtomicLong(641L); public static void setGlobalInitialSeed(final long seed) { seedCounter.set(seed); } public static long reseedThreadLocal() { return reseedThreadLocal(getThreadLocalRandom().nextLong()); } public static long reseedThreadLocal(long seed) { Well19937c random = getThreadLocalRandom(); random.setSeed(seed); return seed; } public static Well19937c getThreadLocalRandom() { return threadLocalRandom.get().generator; } public static RandomDataGenerator getThreadLocalRandomData() { return threadLocalRandom.get().rdi; } private static final class Randomm { final Well19937c generator; final RandomDataGenerator rdi; private Randomm(Well19937c generator) { this.generator = generator; this.rdi = new RandomDataGenerator(generator); } } }