• [.net 多线程] Interlocked实现CAS操作


    Interlocked:为多个线程共享的变量提供原子操作。

    Interlocked.Increment(ref value) 数值加一(原子性操作)
    Interlocked.Decrement(ref value) 数值减一(原子性操作)
    Interlocked.Exchange(ref value1, value2) 交换:把值2赋给值1;返回原值
    Interlocked.CompareExchange(ref value1, value2, value3) 实现比较和交换两种功能:值1和值3比较,如果相同,把值2给值1,不相同则不作任何操作;返回原值(多用于判断条件)(示例3中会用到)
    • 实现原子级运算
     1 int increament = 0;
     2 Thread th1 = new Thread(() =>
     3 {
     4     for (int i = 0; i < 10; i++)
     5         Console.WriteLine($"th1 {Interlocked.Increment(ref increament)}");
     6 });
     7 
     8 Thread th2 = new Thread(() =>
     9 {
    10     for (int i = 0; i < 10; i++)
    11         Console.WriteLine($"th2 {Interlocked.Increment(ref increament)}");
    12 });
    13 
    14 Thread th3 = new Thread(() =>
    15 {
    16     for (int i = 0; i < 10; i++)
    17         Console.WriteLine($"th3 {Interlocked.Increment(ref increament)}");
    18 });
    19 
    20 Thread th4 = new Thread(() =>
    21 {
    22     for (int i = 0; i < 10; i++)
    23         Console.WriteLine($"th4 {Interlocked.Increment(ref increament)}");
    24 });
    25 
    26 th1.Start();
    27 th2.Start();
    28 th3.Start();
    29 th4.Start();
    30 Console.ReadKey();
    实现递增计算

    运行结果:

     1 int increament = 0;
     2 Thread th1 = new Thread(() =>
     3 {
     4     for (int i = 0; i < 10; i++)
     5         //Console.WriteLine($"th1 {Interlocked.Increment(ref increament)}");
     6         Console.WriteLine($"th1 {increament++}");
     7 });
     8 
     9 Thread th2 = new Thread(() =>
    10 {
    11     for (int i = 0; i < 10; i++)
    12         //Console.WriteLine($"th2 {Interlocked.Increment(ref increament)}");
    13         Console.WriteLine($"th2 {increament++}");
    14 });
    15 
    16 Thread th3 = new Thread(() =>
    17 {
    18     for (int i = 0; i < 10; i++)
    19         //Console.WriteLine($"th3 {Interlocked.Increment(ref increament)}");
    20         Console.WriteLine($"th3 {increament++}");
    21 });
    22 
    23 Thread th4 = new Thread(() =>
    24 {
    25     for (int i = 0; i < 10; i++)
    26         //Console.WriteLine($"th4 {Interlocked.Increment(ref increament)}");
    27         Console.WriteLine($"th4 {increament++}");
    28 });
    29 
    30 th1.Start();
    31 th2.Start();
    32 th3.Start();
    33 th4.Start();
    34 Console.ReadKey();
    非原子并行计算

    • 模拟锁

    用Exchange函数实现锁

     1         //0 for false, 1 for true.
     2         private static int usingResource = 0;
     3         //A simple method that denies reentrancy.
     4         static bool UseResource()
     5         {
     6             //0 indicates that the method is not in use.
     7             if (0 == Interlocked.Exchange(ref usingResource, 1))
     8             {
     9                 Console.WriteLine("{0} acquired the lock", Thread.CurrentThread.Name);
    10 
    11                 //Code to access a resource that is not thread safe would go here.
    12 
    13                 //Simulate some work
    14                 Thread.Sleep(500);
    15 
    16                 Console.WriteLine("{0} exiting lock", Thread.CurrentThread.Name);
    17 
    18                 //Release the lock
    19                 Interlocked.Exchange(ref usingResource, 0);
    20                 return true;
    21             }
    22             else
    23             {
    24                 Console.WriteLine("   {0} was denied the lock", Thread.CurrentThread.Name);
    25                 return false;
    26             }
    27         }
    用Exchange模拟锁

    用CompareExchange函数实现锁

     1         private double totalValue = 0.0;
     2 
     3         public double Total { get { return totalValue; } }
     4 
     5         public double AddToTotal(double addend)
     6         {
     7             double initialValue, computedValue;
     8             do
     9             {
    10                 initialValue = totalValue;//---(1)
    11                 computedValue = initialValue + addend;//---(2)
    12 
    13             }
    14             while (initialValue != Interlocked.CompareExchange(ref totalValue,
    15                 computedValue, initialValue));
    16             //Interlocked.CompareExchange:比较totalValue与initialValue是否相同,如果相同,则用computedValue的值覆盖totalValue
    17 
    18             //如果totalValue与initialValue值不相同,则说明在(1)与(2)步骤执行的同时,
    19             //其他线程执行了对totalValue进行了改变
    20             return computedValue;
    21         }
    CompareExchange模拟锁

    原子操作参考:http://www.cnblogs.com/5iedu/p/4719625.html

  • 相关阅读:
    常见错误及解决方案
    使用7zip压解各种文件的经常使用命令
    《鸟哥的Linux私房菜-基础学习篇(第三版)》(六)
    一起talk C栗子吧(第一百二十四回:C语言实例--内置宏)
    逻辑学和计算理论相关概念
    书评第003篇:《0day安全:软件漏洞分析技术(第2版)》
    解释器模式
    面试复习重点——数据结构、操作系统、计算机网络、数据库。
    我们凭什么年薪达到30万以上?
    测试工作中的问题清单
  • 原文地址:https://www.cnblogs.com/deepminer/p/8998155.html
Copyright © 2020-2023  润新知