我對線程和併發性相當缺乏經驗;爲了彌補這一點,我目前正在爲在F#中實現隨機搜索算法而努力。我根據現有C#示例的想法編寫了一個System.Random類的包裝器,但由於我不確定我怎麼會開始單元測試這個錯誤行爲,所以我想聽聽更多有經驗的人想說什麼,如果有明顯的缺陷或我的代碼的改進,無論是由於F#的語法或線程誤區:這是一個適當的線程安全的隨機包裝?
open System
open System.Threading
type Probability() =
static let seedGenerator = new Random()
let localGenerator =
new ThreadLocal<Random>(
fun _ ->
lock seedGenerator (
fun _ ->
let seed = seedGenerator.Next()
new Random(seed)))
member this.Draw() =
localGenerator.Value.NextDouble()
我的這是什麼一樣的理解:ThreadLocal的確保了一個實例,每個線程接收它自己的實例一個隨機,隨機種子由一個共同的靜態隨機提供。這樣,即使該類的多個實例在時間上接近創建,它們也會接收到它們自己的種子,從而避免了「重複」隨機序列的問題。該鎖強制兩個線程不會獲得相同的種子。
這看起來正確嗎?有明顯的問題嗎?
像這樣的代碼的問題是,如果您快速連續生成幾個對象。因爲他們都會有相同的種子。還是你的意思是那些是全局變量? – svick
@svick - 點是爲什麼生成一堆隨機 - 這只是一個隨機的,你可以從多個線程訪問。這是非常簡單的,除非你需要一個可笑的數字的隨機數,它應該沒問題。如果rands是瓶頸,那麼最好用不同的發生器來獲得速度 –
好吧,昂貴的位是每個隨機數的鎖。 –