C#使用Interlocked实现线程同步

通过System.Threading命名空间的Interlocked类控制计数器,从而实现进程 的同步。Iterlocked类的部分方法如下表:

示例,同时开启两个线程,一个写入数据,一个读出数据

代码如下:(但是运行结果却不是我们想象的那样)

 1 static void Main(string[] args)
 2     {
 3       //缓冲区,只能容纳一个字符
 4       char buffer = ',';
 5       string str = ""这里面的字会一个一个读取出来,一个都不会少,,,"";
 6       //线程:写入数据
 7       Thread writer = new Thread(() =>
 8       {
 9         for (int i = 0; i < str.Length; i++)
10         {
11           buffer = str[i];
12           Thread.Sleep(20);
13         }
14       }       
15       );
16       //线程:读出数据
17       Thread Reader = new Thread(() =>
18       {
19         for (int i = 0; i < str.Length; i++)
20         {
21           char chartemp = buffer;
22           Console.Write(chartemp);
23           Thread.Sleep(30);
24         }
25       }
26       );
27       writer.Start();
28       Reader.Start();
29       Console.ReadKey();
30     }

运行结果图:(每次运行结果都不一样) 

 

修改代码如下:

 1 class Program
 2   {
 3     //缓冲区,只能容纳一个字符
 4     private static char buffer;
 5     //标识量(缓冲区中已使用的空间,初始值为0)
 6     private static long numberOfUsedSpace = 0;
 7     static void Main(string[] args)
 8     {
 9       //线程:写入者
10       Thread Writer = new Thread(delegate ()
11       {
12         string str = "这里面的字会一个一个读取出来,一个都不会少,,,";
13         for (int i = 0; i < 24; i++)
14         {
15           //写入数据前检查缓冲区是否已满
16           //如果已满,就进行等待,直到缓冲区中的数据被进程Reader读取为止
17           while (Interlocked.Read(ref numberOfUsedSpace) == 1)
18           {
19             Thread.Sleep(50);
20           }
21           buffer = str[i];  //向缓冲区写入数据
22           //写入数据后把缓冲区标记为满(由0变为1)
23           Interlocked.Increment(ref numberOfUsedSpace);
24         }
25       });
26       //线程:读出者
27       Thread Reader = new Thread(delegate ()
28       {
29         for (int i = 0; i < 24; i++)
30         {
31           //读取数据前检查缓冲区是否为空
32           //如果为空,就进行等待,直到进程Writer向缓冲区中写入数据为止
33           while (Interlocked.Read(ref numberOfUsedSpace) == 0)
34           {
35             Thread.Sleep(50);
36           }
37           char ch = buffer;    //从缓冲区读取数据
38           Console.Write(ch);
39           Interlocked.Decrement(ref numberOfUsedSpace);
40         }
41       });
42       //启动线程
43       Writer.Start();
44       Reader.Start();
45       Console.ReadKey();
46     }

正确结果图:

 原文地址:https://www.jb51.net/article/149543.htm

posted @ 2020-07-01 19:51  摩诘  阅读(878)  评论(1编辑  收藏  举报