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 }
正确结果图: