多线程下的单例模式

转载:http://blog.csdn.net/xxqq0824/article/details/584157

在多线程下的singleton模式是有弊端的,但如何解决呢?办法是使用lock机制。今天研究的lock机制,并且顺便了解了些关于多线程的cpu层面的机制。

在单个cpu的环境下,在系统的某一时间下cpu只能做一件事情,一个时间片(slice),这个是cpu执行最小单位。在系统中有多个进程看起来好像是同时运行,但实际上这些进程都是在一个队列中,排着队。cpu在一个时间片内先执行排到第一位的,当然,在处理排在第一位的进程的时候,很可能一个时间片都过去了,但是这个进程还是没有完,于是cpu管理就把它提到这个等待队列的最后一位,再用一个时间片来执行下一个进程,而一个时间片的时间是不定的,基本上为毫秒级的,所以在这个进程的等待队列中,可能一秒钟就轮循了一遍,即都有过执行,这样就看起来好每个进程都在执行一样。这存在一个问题,就是为什么pcu为什么不一次就把一个进程执行完呢?这样就不需要很麻烦的管理队列问题了。但windows的机制就是这样的,保证公平,并且有个优先原则,比如你这个进程需要1秒就执行完,而排在你前一位的需要10秒才能执行完,于是cpu允许你插队。

当然,还有个休眠队列,当这个线程休眠的话,系统就把这个线程加入到休眠队列,直到你的休眠时间到了,就把你提到等待队列的最后一个,等待cpu光临你了。

lock机制(不知道是不是C#独有的)是一个锁资源的家伙。他能保证你他锁住的东西在语句块内没有执行完,它是不会释放资源,让其他线程访问的。

lock有几种方式。lock(this) ,指锁定整个对象,或者是lock(typeof(A))   (A为这个类的类名)当然可以实现,但是,锁住整个对象,那其他线程要访问这个对象,而并没有涉及到Lock语句内,那也没办法获取lock了的资源(this),或者整个类的资源。最好的解决方案是专门创建一个为锁机制而造的object对象。

下面,写的是个我自认为完美的解决singleton多线程问题的方案,是个范本,其中使用线程休眠,来放大多线程下的singleton错误。

using System;
using System.Threading;

namespace SingleTon
{
 class A
 {
  static readonly object padlock = new object();
  string  s;
  private A(string x)
  {
   s=x;
  }
  static A  a=null;
  public static A GetA(string  s)
  {

   lock(padlock)
   {
    if(a==null)
    {
     Random rd = new Random(unchecked((int)DateTime.Now.Ticks)); 
     int v =rd.Next(10, 1000);
     Thread.Sleep(v);
     a = new A(s);
    }
   }
   return a;
  }
  public override string ToString()
  {
   return s;
  }
 
 }

 class B
 {
  A  a=null;
  public void Test1()
  {
   a = A.GetA("Morning!");
   Console.WriteLine(a.ToString());
  }
  public void Test2()
  {
   a = A.GetA("Afternoon!");
   Console.WriteLine(a.ToString());
  }
 }
 class T
 {
  static void Main()
  {
   B b = new B();
   Thread  t1=new Thread(new ThreadStart(b.Test1));
   Thread  t2=new Thread(new ThreadStart(b.Test2));
   t1.Start();
   t2.Start();

 

  }
 }
}

我让这个线程睡觉是因为让它把时间片交给其他线程,从而使得能够有机会在singleton模式下实现多个对象的错误。

在这样地饿情况下,如果你要是不lock,把Lock语句注解了,就会实现在singleton模式下创建多个对象!

当然还有个小问题,那就是在使用lock的时候,能尽量不锁的语句就放出去,别放在Lock 语句内!道理是显而易见的。

你可能感兴趣的:(thread,多线程,String,object,Random,Class)