22open System
33open System.Threading
44
5- type Example () =
5+ type ThreadLocal () =
66 [<ThreadStatic; DefaultValue>]
7- static val mutable private previous : double
7+ static val mutable private requestId : string option
88
9- [<ThreadStatic; DefaultValue>]
10- static val mutable private sum : double
11-
12- [<ThreadStatic; DefaultValue>]
13- static val mutable private calls : int
14-
15- [<ThreadStatic; DefaultValue>]
16- static val mutable private abnormal : bool
17-
18- static let mutable totalNumbers = 0
19- static let countdown = new CountdownEvent( 1 )
20- static let lockObj = obj ()
21- let rand = Random()
22-
23-
24- member this.Execute () =
25- for threads = 1 to 10 do
26- let newThread = new Thread( ThreadStart this.GetRandomNumbers)
27- countdown.AddCount()
28- newThread.Name <- threads.ToString()
29- newThread.Start()
30- this.GetRandomNumbers()
31- countdown.Wait()
32- printfn $" {totalNumbers:N0} random numbers were generated."
9+ static member PerformLogging () =
10+ Console.WriteLine( $" Thread {Thread.CurrentThread.ManagedThreadId}: Logging request {ThreadLocal.requestId.Value}" )
3311
34- member _.GetRandomNumbers () =
35- // Initialize ThreadStatic fields for this thread.
36- Example.previous <- 0.0
37- Example.sum <- 0.0
38- Example.calls <- 0
39- Example.abnormal <- false
12+ static member PerformDatabaseOperation () =
13+ Console.WriteLine( $" Thread {Thread.CurrentThread.ManagedThreadId}: Processing DB operation for request {ThreadLocal.requestId.Value}" )
4014
41- let mutable i = 0
42- while i < 2000000 do
43- lock lockObj ( fun () ->
44- let result = rand.NextDouble()
45- Example.calls <- Example.calls + 1
46- Interlocked.Increment & totalNumbers |> ignore
47- // We should never get the same random number twice.
48- if result = Example.previous then
49- Example.abnormal <- true
50- i <- 2000001 // break
51- else
52- Example.previous <- result
53- Example.sum <- Example.sum + result )
54- i <- i + 1
55- // get last result
56- if Example.abnormal then
57- printfn $" Result is {Example.previous} in {Thread.CurrentThread.Name}"
15+ static member ProcessRequest ( reqId : obj ) =
16+ ThreadLocal.requestId <- Some( reqId :?> string)
17+ ThreadLocal.PerformDatabaseOperation()
18+ ThreadLocal.PerformLogging()
5819
59- printfn $" Thread {Thread.CurrentThread.Name} finished random number generation."
60- printfn $" Sum = {Example.sum:N4}, Mean = {Example.sum / float Example.calls:N4}, n = {Example.calls:N0}\n "
61- countdown.Signal() |> ignore
20+ [<EntryPoint>]
21+ let main _ =
22+ let thread1 = Thread( ThreadStart( fun () -> ThreadLocal.ProcessRequest( " REQ-001" )))
23+ let thread2 = Thread( ThreadStart( fun () -> ThreadLocal.ProcessRequest( " REQ-002" )))
6224
63- let ex = Example()
64- Thread.CurrentThread.Name <- " Main"
65- ex.Execute()
25+ thread1.Start()
26+ thread2.Start()
27+ thread1.Join()
28+ thread2.Join()
6629
67- // The example displays output similar to the following:
68- // Thread 1 finished random number generation.
69- // Sum = 1,000,556.7483, Mean = 0.5003, n = 2,000,000
70- //
71- // Thread 6 finished random number generation.
72- // Sum = 999,704.3865, Mean = 0.4999, n = 2,000,000
73- //
74- // Thread 2 finished random number generation.
75- // Sum = 999,680.8904, Mean = 0.4998, n = 2,000,000
76- //
77- // Thread 10 finished random number generation.
78- // Sum = 999,437.5132, Mean = 0.4997, n = 2,000,000
79- //
80- // Thread 8 finished random number generation.
81- // Sum = 1,000,663.7789, Mean = 0.5003, n = 2,000,000
82- //
83- // Thread 4 finished random number generation.
84- // Sum = 999,379.5978, Mean = 0.4997, n = 2,000,000
85- //
86- // Thread 5 finished random number generation.
87- // Sum = 1,000,011.0605, Mean = 0.5000, n = 2,000,000
88- //
89- // Thread 9 finished random number generation.
90- // Sum = 1,000,637.4556, Mean = 0.5003, n = 2,000,000
91- //
92- // Thread Main finished random number generation.
93- // Sum = 1,000,676.2381, Mean = 0.5003, n = 2,000,000
94- //
95- // Thread 3 finished random number generation.
96- // Sum = 999,951.1025, Mean = 0.5000, n = 2,000,000
97- //
98- // Thread 7 finished random number generation.
99- // Sum = 1,000,844.5217, Mean = 0.5004, n = 2,000,000
100- //
101- // 22,000,000 random numbers were generated.
30+ Console.WriteLine( " Main thread execution completed." )
31+ 0
10232// </Snippet1>
0 commit comments