zoukankan      html  css  js  c++  java
  • 自旋锁-SpinLock(.NET 4.0+)

    短时间锁定的情况下,自旋锁spinlock更快。(因为自旋锁本质上不会让线程休眠,而是一直循环尝试对资源访问,直到可用。所以自旋锁线程被阻塞时,不进行线程上下文切换,而是空转等待。对于多核CPU而言,减少了切换线程上下文的开销,从而提高了性能

    以下是简单实例(并行执行10000次,每次想list中添加一项。执行完后准确的结果应该是10000):

    foo1:使用系统的自旋锁。

    foo4:不使用锁。结果必然是不正确的。

    foo5:通过Interlocked实现自旋锁。

      1    public class SpinLockDemo
      2     {
      3         int i = 0;
      4         List<int> li = new List<int>();
      5         SpinLock sl = new SpinLock();
      6         int signal = 0;
      7 
      8         public void Execute() 
      9         {
     10             foo1();
     11             //li.ForEach((t) => { Console.WriteLine(t); });
     12             Console.WriteLine("Li Count - Spinlock: "+li.Count);
     13             li.Clear();
     14             foo4();
     15             Console.WriteLine("Li Count - Nolock: " + li.Count);
     16             li.Clear();
     17             foo5();
     18             Console.WriteLine("Li Count - Customized Spinlock: " + li.Count);
     19 
     20         }
     21 
     22         public void foo1()
     23         {
     24             Parallel.For(0, 10000, r =>
     25             {
     26                 bool gotLock = false;     //释放成功
     27                 try
     28                 {
     29                     sl.Enter(ref gotLock);    //进入锁
     30                     //Thread.Sleep(100);
     31                     if (i == 0)
     32                     {
     33                         i = 1;
     34                         li.Add(r);
     35                         i = 0;
     36                     }
     37                 }
     38                 finally
     39                 {
     40                     if (gotLock) sl.Exit();  //释放
     41                 }
     42 
     43             });
     44         }
     45 
     46         public void foo4()
     47         {
     48             Parallel.For(0, 10000, r =>
     49             {
     50                 if (i == 0)
     51                 {
     52                     i = 1;
     53                     li.Add(r);
     54                     i = 0;
     55                 }
     56             });
     57         }
     58 
     59         public void foo5()
     60         {
     61             Parallel.For(0, 10000, r =>
     62             {
     63                 while (Interlocked.Exchange(ref signal, 1) != 0)//加自旋锁
     64                 {}
     65                 li.Add(r);
     66                 Interlocked.Exchange(ref signal, 0);  //释放锁
     67             });
     68 
     69         }
     70 
     71         public void foo6()
     72         {
     73             //Console.WriteLine(i);
     74             //Task.Run(new Action(foo2)).ContinueWith(new Action<Task>(t =>
     75             //{
     76             //    Console.WriteLine("foo2 completed: " + i);
     77             //}));
     78             //Console.WriteLine(i);
     79             //Task.Run(new Action(foo2)).ContinueWith(new Action<Task>(t =>
     80             //{
     81             //    Console.WriteLine("foo3 completed: " + i);
     82             //}));
     83             //Console.WriteLine(i);
     84         }
     85         public void foo2()
     86         {
     87             bool lck = false;
     88             sl.Enter(ref lck);
     89             Thread.Sleep(100);
     90             ++i;
     91             if (lck) sl.Exit(); 
     92         }
     93 
     94         public void foo3()
     95         {
     96             bool lck = false;
     97             sl.Enter(ref lck);
     98             ++i;
     99             if (lck) sl.Exit();
    100         }
    101     }

    结果如下:

  • 相关阅读:
    安装selenium
    android MediaPlayer API 详解
    如鹏网学习笔记(六)ADO.Net基础
    如鹏网学习笔记(五)MySql基础
    如鹏网学习笔记(七)HTML基础
    10.12作业
    10.10作业
    201671010111 201620172 《java程序设计》 学习态度的重要性
    201671010111 201620172《面向对象的程序设计》 编程总结
    201671010111 201620172《Java程序设计》再看java
  • 原文地址:https://www.cnblogs.com/1zhk/p/5269722.html
Copyright © 2011-2022 走看看