• 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

  • 相关阅读:
    Photoshop给草坡上的人物加上大气的霞光
    Photoshop给人像加上个性裂纹肌肤
    Photoshop快速给美女人像换头发
    Oracle和SQLite位数不足补0
    Oracle和Postgis数据库地理坐标系下面积计算
    SQLite3中自增主键归零方法
    Arcgis-Tools_06矢量数据按国土分解
    Arcgis-Issues_03Arcgis最佳路径分析
    Arcgis-Tools_05批量导出地图
    Oracle_C#连接Oracle数据库
  • 原文地址:https://www.cnblogs.com/mojiejushi/p/13221151.html
Copyright © 2020-2023  润新知