É válido compartilhar uma instância da Random
classe entre vários threads? E chamar nextInt(int)
de vários tópicos em particular?
java
multithreading
random
thread-safety
Shcheklein
fonte
fonte
java.util.concurrent.ThreadLocalRandom
.Respostas:
É thread-safe no sentido de que ainda irá gerar números aleatórios quando usado por vários threads.
A implementação Sun / Oracle JVM usa synchronized e AtomicLong como seed para melhorar a consistência entre os threads. Mas isso não parece ser garantido em todas as plataformas na documentação.
Eu não escreveria seu programa para exigir tal garantia, especialmente porque você não pode determinar a ordem em que
nextInt()
será chamado.fonte
É thread-safe, embora nem sempre tenha sido.
Consulte http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6362070 para obter mais detalhes.
fonte
De acordo com a documentação, Math.random () garante que é seguro para uso por várias threads. Mas a classe Random não. Eu diria que então você terá que sincronizar isso sozinho.
fonte
Sim, Random é thread-safe. o
nextInt()
método chama onext(int)
método protegido que usaAtomicLong seed, nextseed
(comprimento atômico) para gerar uma próxima semente.AtomicLong
é usado para segurança de thread na geração de sementes.fonte
Como disse, é thread save, mas pode ser sábio usar de
java.util.concurrent.ThreadLocalRandom
acordo com este artigo (link morto). ThreadLocalRandom também é uma subclasse de Random, portanto, é compatível com versões anteriores.fonte
Não há razão para que vários tópicos não possam usar o mesmo Random. No entanto, uma vez que a classe não é explicitamente thread-safe e mantém uma sequência de números pseudo-aleatórios por meio da semente. Vários threads podem terminar com o mesmo número aleatório. Seria melhor criar vários Randoms para cada segmento e semeá-los de maneira diferente.
EDITAR : Acabei de notar que a implementação da Sun usa AtomicLong, então acho que é thread-safe (como também observado por Peter Lawrey (+1)).
EDIT2 : OpenJDK também usa AtomicLong para a semente. Como outros já disseram, ainda não é bom confiar nisso.
fonte
Veja como lidei com o problema sem presumir que Random usa variáveis atômicas. Ele ainda pode colidir aleatoriamente se
currentTime * thread id
for igual em algum momento no futuro, mas isso é raro o suficiente para minhas necessidades. Para realmente evitar a possibilidade de colisões, você pode fazer com que cada solicitação espere por um registro de data e hora exclusivo.fonte
(24*60*60*1000)
parte é significativa?(24*60*60*1000)
era para que um thread com ID12
emxxxxxxxxxx045
millis não fosse propagado da mesma forma que um thread22
emxxxxxxxxxx035
millis. No entanto, não tenho nenhum bom motivo para supor que os IDs de thread sejam incrementais e não há um bom motivo para pensar que estou criando threads mais aleatoriamente amanhã do que hoje. Simplifiquei a alg agora e atualizei a descrição para identificar a deficiência.A
Random
classe não está configurada para uma instância a ser usada em vários threads. Claro, se você fez isso, provavelmente aumentará a possibilidade de se tornar imprevisível e mais próximo dos números aleatórios . Mas, como é um gerador pseudo-aleatório, não consigo ver por que você precisaria compartilhar uma instância. Existe um requisito mais específico?fonte