簡體   English   中英

Java在多線程環境中配置隨機數生成器

[英]Java Configuring random number generators in multi-threaded environment

我有一個使用偽隨機數的應用程序。 在測試應用程序時,我需要可重復性,我通過為隨機數生成器使用種子來安排可重復性。 當前,RNG在使用它作為靜態變量的類中聲明: private static Random rng = new Random(seed) 我有幾個問題。

  1. 鑒於我想播種RNG以獲得可重復性,因此將變量聲明為static有意義嗎?
  2. 我可能需要添加更多需要隨機數的不同類。 我是否應該將RNG移到一個單獨的類,以便仍可以在整個應用程序中使用一個種子? 如果是這樣,我應該使用static Random還是singleton對象?
  3. 如果我決定在多個線程中使用隨機數會怎樣? 似乎如果我使用類似2.的策略,我可能仍然會失去可預測性,因為我無法確定地說線程將訪問RNG的順序。 RNG仍將生成相同的,可預測的隨機數序列,但是從程序的一次運行到另一輪,抓取序列中第一個(或第n個)隨機數的線程可能會有所不同。
  4. 這對我來說表明,每個線程都需要自己的RNG,以便在所有運行中都可重現結果。 這是否意味着每個線程都需要自己的種子? 如果是這樣,那將保證可重復性,還是我需要做其他事情來消除由多個線程導致的隨機性?
  5. 有沒有一種方法可以從單個數字生成種子,從而最大程度地減少不同RNG之間的相關性?

換句話說,如果線程0具有Random thread0RNG = new Random(seed)且線程1具有Random thread1RNG = new Random(seed) ,則我只需要一個種子,但是每個線程中的隨機數將高度相關。 我可以有兩個種子,但是然后我無法將程序的運行與在命令行上傳遞的單個數字相關聯。 是否可以說出seed0 = someFunction(seed,0)seed1 = someFunction(seed,1)嗎?

是的,您應該為每個線程分配自己的Random對象,以避免由於線程計時而產生不可重復的交織。

您都可以使用相同的編號為它們播種,但隨后它們都將獲得完全相同的編號序列。 我不知道這是不是一個問題。

如果有問題,則可以有一個“主”隨機對象為其他種子生成種子。 每次創建新線程時,請從主線程獲取種子。 但是,您必須確保每次都以相同的順序創建所有線程(或至少檢索種子)。

首先, Random是線程安全的,因此您可以在多個線程中安全地使用它,盡管由於鎖定,只有一個Random實例可能會導致性能下降。 為避免這種情況,請改用ThreadLocalRandom

但這不是解決方案,如果您的情況需要可預測性。 在並發環境中只有一個共享的RNG將永遠不可預測。 因此,您是對的, 每個線程需要一個實例 ,並且每個實例都必須使用種子進行初始化。

但是,如果所有RNG實例都使用相同的種子,則生成的隨機序列不僅將高度相關,而且將是相同的! 因此,您必須為所有RNG使用不同的種子

因此,我建議使用中央RNG為所有其他RNG生成種子 但是請注意,這僅是可預見的,前提是RNG的播種順序已明確定義-同樣,在並發環境中,這可能不是直截了當的,而是可行的。

對每個線程使用RNG, 例如 ThreadLocalRandom 如果每個線程都有自己的生成器,則多線程不會影響隨機性。 種子的選擇取決於您。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM