Setiap kali Anda melakukannya new Random()
diinisialisasi menggunakan jam. Ini berarti bahwa dalam loop ketat Anda mendapatkan nilai yang sama banyak kali. Anda harus menyimpan satu instance Acak dan terus menggunakan Next pada instance yang sama .
//Function to get a random number
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public static int RandomNumber(int min, int max)
{
lock(syncLock) { // synchronize
return random.Next(min, max);
}
}
Sunting (lihat komentar): mengapa kita perlu di lock
sini?
Pada dasarnya, Next
akan mengubah keadaan internal Random
instance. Jika kami melakukan itu secara bersamaan dari beberapa utas, Anda dapat berdebat "kami baru saja membuat hasilnya lebih acak", tetapi apa yang sebenarnya kami lakukan berpotensi melanggar implementasi internal, dan kami juga bisa mulai mendapatkan angka yang sama dari utas berbeda, yang mungkin menjadi masalah - dan mungkin tidak. Namun, jaminan apa yang terjadi secara internal adalah masalah yang lebih besar; karena Random
tidak tidak membuat jaminan benang-keselamatan. Jadi ada dua pendekatan yang valid:
- Sinkronisasi agar kami tidak mengaksesnya secara bersamaan dari utas yang berbeda
- Gunakan
Random
contoh berbeda per utas
Baik bisa baik-baik saja; tetapi mutexing satu contoh dari beberapa penelepon pada saat yang sama hanya meminta masalah.
The lock
mencapai pertama (dan sederhana) dari pendekatan ini; Namun, pendekatan lain mungkin:
private static readonly ThreadLocal<Random> appRandom
= new ThreadLocal<Random>(() => new Random());
ini kemudian per-utas, jadi Anda tidak perlu melakukan sinkronisasi.
new Random().Next((int)0xFFFF, (int)0xFFFFFF) % 256);
tidak menghasilkan angka "acak" yang lebih baik dari.Next(0, 256)