2012-04-11 17 views
5

Piszę konstruktor klasy z polem dziesiętnym, który musi być zainicjalizowany przez losową wartość. Wystarczy jedno małe pole i muszę utworzyć nowy obiekt Random. Po pierwsze wygląda na uciążliwe, aw drugim może powstać wiele równych wartości, w przypadku tworzenia wielu obiektów w jednym wycinku czasu (new Random() jest euqal do new Random(System.currentTimeMillis()), a równy czasMillis zawiera równe wartości losowe).Uzyskaj losową wartość bez tworzenia obiektu `Losowego`

Jaki jest najlepszy sposób na uniknięcie tego?

+0

Próbowałem znaleźć rozwiązanie w 'DatagramSocket()' (potrzebuje w losowej wartości gniazda), ale nie udało się. – Jofsey

+1

Jaką wersję Java używasz? –

+0

Używam Java 7. – Jofsey

Odpowiedz

9

nowy random() jest euqal do nowego random (System.currentTimeMillis())

Nie, tak nie jest. W ostatnich JDKs jest to new Random(seedUniquifier()^System.nanoTime()); , gdzie seedUniquifier() opiera się na uruchomieniu liniowego generatora kongruencji na statycznym AtomicLong. W związku z tym właściwie bezpieczne jest tworzenie obiektów w zależności od potrzeb.

Oczywiście, zawsze możesz mieć pole private static Random i użyć go w konstruktorze.

6

Szukasz Math.random. Jest to statyczna metoda, która domyślnie inicjuje nowy obiekt Random przy pierwszym wywołaniu, a następnie używa tego obiektu. Dzięki temu można dzielić pojedynczy obiekt Random między wszystkimi inicjacjami pól statycznych, bez konieczności samodzielnego zarządzania obiektem Random.

+1

Ma to tę wadę, że nie ma tak przyjemnego API jak 'Random'. W pojedynczym statycznym polu końcowym nie ma zbyt wiele "zarządzania" ... –

+0

Byłoby wspaniale mieć taką samą metodę dla liczb całkowitych. Do tego czasu wolę używać pola ** static ** 'Random' w mojej własnej klasie. – Jofsey

2

Czy używasz Java 7, Random jest threadsafe, co zostało udokumentowane:

Przypadki java.util.Random są threadsafe. Jednak jednoczesne korzystanie z tej samej instancji java.util.Random w wątkach może napotkać rywalizację i wynikającą z tego niską wydajność. Zamiast tego należy rozważyć użycie ThreadLocalRandom w projektach wielowątkowych.

Więc może wystarczy użyć:

private static final Random random = new Random(); 

... lub użyj ThreadLocalRandom jeśli masz zamiar używać tego z wielu wątków. Oczywiście nadal nie będzie tak przypadkowa jak SecureRandom. Zasadniczo dostosuj swój wybór do swoich potrzeb.

Powiązane problemy