2017-01-24 2 views
0

Я работаю над веб-приложением, где мне нужно создать случайное число для каждого запроса. Запрос попадет в конкретное ведро из набора ведер. Случайные числа, сгенерированные для данного ведра, должны иметь равномерное распределение. Я планирую использовать карту, которая имеет SplittableRandom экземпляров против ведра идентификаторов, как этоIs SplittableRandom.split() threadsafe?

buketId -> SplittableRandom

Чтобы развлечь веб-запрос, я первый проверить bucketId, указанный в запросе. Затем я выбираю соответствующий экземпляр SplittableRandom и вызывается split() на нем. В режиме тяжелой нагрузки split() будет вызываться в одном экземпляре несколькими потоками. Является ли этот подход потоком безопасным?

+1

Нет. Либо создавайте свежие экземпляры локально, либо используйте обычный «Случайный». – shmosel

ответ

3

От Javadoc

Экземпляры SplittableRandom являются не потокобезопасной. Это , предназначенные для разделения, а не совместного использования, по потокам. Например, вычисление java.util.concurrent.ForkJoinTask fork/join-style с использованием случайных чисел может включать в себя конструкцию формы new Subtask(aSplittableRandom.split()).fork().

split() метод возвращает новый экземпляр SplittableRandom основанный на this.

public SplittableRandom split() { 
    return new SplittableRandom(nextLong(), mixGamma(nextSeed())); 
} 

mixGamma() метод поточно-, но требует, чтобы nextSeed() (как в split() и nextLong()) не является, так как они изменяют нелетучие long seed без какого-либо механизма синхронизации.

+1

Почему вы заключаете 'split()' является потокобезопасным? – shmosel

+1

@shmosel Вы правы, это не так (когда вы переходите к 'nextSeed()'). – Kayaman