zoukankan      html  css  js  c++  java
  • [.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

  • 相关阅读:
    JS中的“&&”与“&”和“||”“|”有什么区别?
    深入理解CSS过度动画transition
    使用navigator.userAgent查看浏览器当前模式和版本
    node.js面试题
    Javascript 中的 ...(展开运算符)
    JavaScript立即执行函数
    JavaScript实现继承的6种方式
    JavaScript的排序算法--冒泡、选择、直接插入
    JavaScript RegExp 对象
    (CVPR 2020 Oral)最新Scene Graph Generation开源框架
  • 原文地址:https://www.cnblogs.com/deepminer/p/8998155.html
Copyright © 2011-2022 走看看