2010-09-25 75 views
4

我有一個代表硬幣的類,可以用Coin.Flip()方法翻轉。 Flip()使用random.Next(2);得到0或1代表正面或反面。這工作很好..有點。C#的問題隨機類

對於該程序,我需要有2個硬幣,我可以說讓coin1和coin2。

COIN2總是需要COIN1後直奔翻轉,我可以用做:

coin1.Flip(); 
coin2.Flip(); 

這應該工作,對不對?

那好吧!每次運行這兩行代碼時,兩個硬幣的結果都相同!

面值存儲在臉上幣類,它是這樣定義裏面:

private int face; 

我看不出有什麼毛病我都幹了些什麼,但每一次我運行代碼,它們最終完全相同。

哦也,隨機在硬幣類中定義的,以及像這樣:

private Random random = new Random(); 

感謝您的幫助!

編輯:這裏的翻轉(),它的工作原理是,隨機是靜態的。

public void Flip() { 
     face = random.Next(2); 
    } 
+0

你能展示Flip的實現嗎? – 2010-09-25 01:21:55

+0

注意:如果它是靜態的,你應該同步它,或者使它具體線程,因爲它沒有被列爲線程安全 – 2010-09-25 06:59:41

回答

6

隨機數生成器需要種子值。具有相同種子的RNG將產生相同的隨機數字流。

默認情況下,System.Random使用當前時間作爲種子。如果您幾乎立即創建兩個實例,它們都可能具有相同的時間值,因此會生成相同的隨機數字序列。

您可以將Random移動到靜態成員,以便所有Coin共享相同的RNG,但請注意System.Random沒有記錄爲線程安全,因此您不能在不同步的線程上使用多個Coin,而無需進行某些同步。

+0

感謝隊友,我在發佈之後正在考慮這個權利。會給它一個鏡頭。 – Azz 2010-09-25 01:46:04

+0

這是更好的。再次感謝! – Azz 2010-09-25 01:53:01

+0

爲您的Coin()創建一個重載可能是一個好主意,它允許您傳遞一個隨機流,並且默認的構造函數使用靜態隨機流。通過這種方式,您可以通過爲每個線程創建單獨的rng來解決任何同步問題 – cordialgerm 2010-09-25 03:03:41

3

我的猜測是,你可能要重新定義你的random變量,在類的級別,如:

private static Random random = new Random(); 

這將使到Flip()每次調用使用相同的發電機,而不是不斷補種。如果您爲每次調用創建Random實例,並且將兩次調用非常靠近,則可能會得到相同的種子,因此也會得到相同的值。