2012-04-01 14 views
11

Ho un grande programma distribuito su molti server fisici diversi, ogni programma genera molti thread, ogni thread usa Math.random() nelle sue operazioni per disegnare un pezzo da molti pool di risorse comuni.come random è Math.random() in java su diversi jvms o macchine diverse

L'obiettivo è utilizzare le piscine in modo uniforme su tutte le operazioni. A volte, non appare così casuale guardando un'istantanea su un pool di risorse per vedere quali pezzi sta ottenendo in quel momento (potrebbe effettivamente essere, ma è difficile da misurare e scoprire di sicuro).

C'è qualcosa che è meglio di Math.random() e funziona altrettanto buono (non molto peggio almeno)?

+0

+1 per una buona domanda. Per favore fatemi sapere se trovate una risposta :) –

+0

Si prega di dare un'occhiata al seguente link. http: //www.coderanch.it/t/510167/java/java/Failer generatore casuale –

+0

Perché non utilizzare alcuni programmi di pianificazione per i pool di risorse comuni? –

risposta

2

Math.random() è basato su java.util.Random, che si basa su un linear congruential generator. Ciò significa che la casualità non è perfetta, ma abbastanza buona per la maggior parte dei compiti, e sembra che dovrebbe essere sufficiente per il tuo compito.

Tuttavia, sembra che si stia utilizzando il valore di ritorno double di Math.random() per scegliere tra un numero fisso di scelte, che potrebbe ulteriormente peggiorare la qualità della casualità. Sarebbe meglio usare java.util.Random.nextInt() - assicurati di riutilizzare lo stesso oggetto Random.

A volte, non sembra così casuale, cercando in un'istantanea su un pool di risorse per vedere quali pezzi si sta facendo in quel momento

I nostri cervelli sono veramente bravo a macchia modelli in perfetta casualità , quindi questo significa quasi nulla.

+0

buon punto su Random.nextInt(), attualmente semplicemente moltiplicare il doppio casuale per n e quindi arrotondarlo all'intero più vicino, è molto diverso da Random(). NextInt()? – user881480

+0

@ user881480: sì - Casuale produce numeri interi, Math.random() fa un lavoro extra per convertirlo in un doppio, solo per convertirlo nuovamente in un int. Questa doppia conversione potrebbe ridurre la qualità della casualità (non proprio certa, ma potrebbe essere). –

0

Questo thread può essere utile: How good is java.util.Random?

altre alternative:

  • generare un seme a caso quando init l'istanza casuale
  • se si utilizza l'uso di Linux/dev/urandom
+0

Non voglio chiamare il processo esterno da Java poiché degrada le prestazioni, sto eseguendo una velocità di 1 operazione al secondo e ci sono molte (centinaia di migliaia o milioni) al giorno su un server. – user881480

+0

quindi la cosa più facile che posso fare è creare il tuo generatore con un periodo più lungo (come descritto nel link). devi anche ricordare che la possibilità di ottenere 1,1,1,1,1 è la stessa possibilità di 45,1002,783,199,6 – shem

1

L'algoritmo di Math.Random è "abbastanza casuale" per qualsiasi piattaforma. Il modello matematico utilizzato per creare numeri psuedo-casuali è buono. Dipende da quanti thread usi. Per tutto tranne un numero molto elevato di thread, questo non ti darà una distribuzione uniforme (la natura dei numeri casuali), e quindi Math.random() ti darà un sacco di spese generali.

Provare un'opzione migliore: creare una classe di pool di risorse, che li distribuisca in modo uniforme, quindi mantenere la sezione critica nel metodo "distribuisci" protetto.

+0

perché i numeri casuali non ti darebbero una distribuzione uniforme? nel mio caso il numero di thread per programma è di poche centinaia, ma ogni thread esegue molte operazioni (1 al secondo, in cui ogni operazione chiama Math.random()). – user881480

+0

in che modo una classe di pool di risorse distribuisce le risorse casualmente? deve usare Math.random()? – user881480

+0

Non è necessario distribuirlo in modo casuale, basta creare una semplice classe chiamata Risorse, un metodo nextResource() sincronizzato. In questo modo continui a esaminarli uno per uno, assicurandoti una distribuzione uniforme. Inoltre, l'utilizzo di centinaia di thread crea un sovraccarico maggiore rispetto al tempo risparmiato tranne in alcuni casi molto specifici; è necessario limitare la quantità di thread a ciò che il sistema può utilizzare in modo efficiente. – user1304831

0

Per javadoc Math.random() è solo un modo semplice di utilizzare java.util.Random. Detto questo è solo un algoritmo casuale pseudo. Un modo semplice per verificare quanto sia casuale un algoritmo, è disegnando punti casuali su griglia x/y. Non dovresti trovare alcun motivo.

Per ottenere numeri di ramdom reali è possibile utilizzare servizi come http://www.random.org. Se questo è lento, forse chiamalo regolarmente per seminare java.util.Random potrebbe avvicinarti al vero casuale.

+0

in che modo il nuovo java.util.Random() ottiene un seed probabilmente distinto? – user881480

Problemi correlati