代码改变世界

.NET中简易实现线程安全

2012-09-10 19:32  uonun  阅读(468)  评论(0编辑  收藏  举报

在.NET中要实现线程安全,可有多种途径:

1. 使用 lock 关键字:

 1 using System;
 2 using System.Threading;
 3 
 4 namespace UDNZ.SynTest
 5 {
 6     class Program
 7     {
 8         static int _x = 0;
 9         static int _n = 1000000;
10         static object _lock = new object();
11 
12         static void Main(string[] args)
13         {
14             EventWaitHandle w1 = new EventWaitHandle(false, EventResetMode.AutoReset);
15             EventWaitHandle w2 = new EventWaitHandle(false, EventResetMode.AutoReset);
16             EventWaitHandle w3 = new EventWaitHandle(false, EventResetMode.AutoReset);
17             EventWaitHandle w4 = new EventWaitHandle(false, EventResetMode.AutoReset);
18 
19             while (true)
20             {
21                 _x = 0;
22                 new Thread((ThreadStart)delegate { SynTest(); w1.Set(); }).Start();
23                 new Thread((ThreadStart)delegate { SynTest(); w2.Set(); }).Start();
24                 new Thread((ThreadStart)delegate { SynTest(); w3.Set(); }).Start();
25                 new Thread((ThreadStart)delegate { SynTest(); w4.Set(); }).Start();
26 
27                 EventWaitHandle.WaitAll(new WaitHandle[] { w1, w2, w3, w4 });
28                 Console.WriteLine(_x.ToString());
29                 Thread.Sleep(1000);
30             }
31         }
32 
33         static void SynTest()
34         {
35             lock (_lock)
36             {
37                 for (int i = 0;i < _n;i++)
38                 {
39                     _x++;
40                 }
41             }
42         }
43     }
44 }

 

2. 使用 MethodImplOptions.Synchronized。

 1 using System;
 2 using System.Threading;
 3 using System.Runtime.CompilerServices;
 4 
 5 namespace UDNZ.SynTest
 6 {
 7     class Program
 8     {
 9         static int _x = 0;
10         static int _n = 1000000;
11 
12         static void Main(string[] args)
13         {
14             EventWaitHandle w1 = new EventWaitHandle(false, EventResetMode.AutoReset);
15             EventWaitHandle w2 = new EventWaitHandle(false, EventResetMode.AutoReset);
16             EventWaitHandle w3 = new EventWaitHandle(false, EventResetMode.AutoReset);
17             EventWaitHandle w4 = new EventWaitHandle(false, EventResetMode.AutoReset);
18 
19             while (true)
20             {
21                 _x = 0;
22                 new Thread((ThreadStart)delegate { SynTest(); w1.Set(); }).Start();
23                 new Thread((ThreadStart)delegate { SynTest(); w2.Set(); }).Start();
24                 new Thread((ThreadStart)delegate { SynTest(); w3.Set(); }).Start();
25                 new Thread((ThreadStart)delegate { SynTest(); w4.Set(); }).Start();
26 
27                 EventWaitHandle.WaitAll(new WaitHandle[] { w1, w2, w3, w4 });
28                 Console.WriteLine(_x.ToString());
29                 Thread.Sleep(1000);
30             }
31         }
32 
33         [MethodImpl(MethodImplOptions.Synchronized)]
34         static void SynTest()
35         {
36             for (int i = 0;i < _n;i++)
37             {
38                 _x++;
39             }
40         }
41     }
42 }

 

3. 使用 System.Threading.Mutex 或 System.Threading.Monitor (略)

 

4. 若需要Queue、Dictionary等保证线程安全,可以这样使用:

 1 using System.Collections;
 2 using System.Collections.Concurrent;
 3 
 4 namespace UDNZ.SynTest
 5 {
 6     class Program
 7     {
 8         static void Main(string[] args)
 9         {
10             // ...
11             Queue unsafeQ = new Queue();
12             Queue safeQ = Queue.Synchronized(unsafeQ);
13 
14             Stack unsafeS = new Stack();
15             Stack safeS = Stack.Synchronized(unsafeS);
16 
17             ConcurrentQueue<string> concQ = new ConcurrentQueue<string>();
18             ConcurrentBag<string> concB = new ConcurrentBag<string>();
19             ConcurrentDictionary<intstring> concD = new ConcurrentDictionary<intstring>();
20             ConcurrentStack<string> concS = new ConcurrentStack<string>();
21             // ...
22         }
23     }
24 }