2017-01-24 2 views
0

Ich arbeite an einer Webanwendung, wo ich für jede Anfrage eine Zufallszahl generieren muss. Die Anfrage trifft einen bestimmten Bucket aus einer Gruppe von Buckets. Die für einen bestimmten Bucket generierten Zufallszahlen sollten eine gleichmäßige Verteilung aufweisen. Ich plane eine Karte zu verwenden, die wie eine SplittableRandom Instanzen gegen Eimer ids hat diesesIst SplitTableRandom.split() threadsafe?

buketId -> SplittableRandom

Um eine Web-Anfrage unterhält ich die bucketId zunächst prüfen, in der Anforderung angegeben. Dann wähle ich die entsprechende SplittableRandom-Instanz und rufe split() darauf auf. Unter Schwerlast wird die split() -Methode für dieselbe Instanz von mehreren Threads aufgerufen. Ist dieser Ansatz sicher?

+1

Nein. Erstellen Sie entweder neue Instanzen lokal oder verwenden Sie ein normales 'Random'. – shmosel

Antwort

3

Vom javadoc

Instanzen SplittableRandom sind nicht Thread-sicher. Sie sind entworfen, um geteilt zu werden, nicht geteilt, über Threads. Zum Beispiel kann eine java.util.concurrent.ForkJoinTask Gabel/join-Stil Berechnung Verwendung von Zufallszahlen könnte eine Konstruktion der Form new Subtask(aSplittableRandom.split()).fork() umfasst.

split() Die Methode liefert eine neue Instanz von SplittableRandom basierend auf this.

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

mixGamma() Die Methode ist threadsicher, aber ruft nextSeed() (beide in split() und nextLong()) nicht, da sie den nichtflüchtigen long seed ohne Synchronisations-Mechanismus modifizieren.

+1

Warum schließen Sie, dass 'split()' Thread-sicher ist? – shmosel

+1

@smosel Du hast recht, es ist nicht (wenn du zu "nextSeed()" gehst). – Kayaman