面向对象设计模式点滴(2)之Singleton

意图:保证一个类仅有一个实例,并提供一个该实例的安全访问点。举不太正确的例子,例如防火墙(有谁能将同一防火墙开两次?),当然这里的“谁”不一定是客户(人),而是客户程序,调用该实例的程序。

错误的看法有人说,new一次不就行了吗?保证不new第二次就行!

这样做不好,如果要每一个调用该实例的客户程序都保证只new一次,是否会很麻烦?也很不安全。我们将这个“只生成一个实例”的需求交由类的设计者本身保证,那么调用该实例的若干客户程序会省下大堆麻烦和安全隐患。

Demo:
class Singleton
{
   
private static Singleton instance;
   
// Constructor
   private Singleton() {}//关键之中的关键,如果没有构造函数,C#编译器会默认为public Singleton()
//私有构造函数,这样做就可以防止其他类,想new就new ,也可以protected来允许派生类调用
  
    public static Singleton Instance()
    
{
      
//通常 使用晚加载,用户调用了Singleton.Instance()才new一个实例
        if( instance == null )
            instance 
= new Singleton(); 
         
return instance;
     }
//只有在本类中才能new一个实例,如果有实例
//存在,则返回自己
}
通过上面的Demo,有一下几点使用总结:
1  应用在单线程中,非多线程,显而易见,如果线程B在线程A没有new之前执行判断语句
if( instance == null ),则线程B又会new一个instance
2  Singleton只考虑了对象创建管理,没考虑垃圾回收。这并不是该模式的局限性,而是没必要考虑
,只有一个实例,占用不了多少资源。如果类大得不回收不行,则要重构了。
3 一般不支持序列化(序列化的实现还不太明白,这里先跳过去)

多线程的应用:
希望各位帮帮忙解答:
using System;
using
 System.Threading;
class
 Singleton
{
    
private static volatile
 Singleton instance;
    
private static object lockHelper=new
 Object();
    
protected Singleton() {}

    
public static Singleton Instance()
    
{
        
if( instance == null
 )
        
{
            
lock
(lockHelper)
            
{
                
if( instance == null
 )
                
{
                    instance 
= new
 Singleton();
                }

            }

        }

//        if( instance == null )
//
        {            
//
            instance = new Singleton();                
//        }

        return instance;
    }

}


public class Client
{
    
private static
 Singleton s1;
    
private static
 Singleton s2;
    
static public void
 dosomwork1()
    
{
        s1
=
Singleton.Instance();
    }

    
static public void dosomwork2()
    
{
        s2
=
Singleton.Instance();
    }

    
public static void Main()
    
{
        Thread t1
=new Thread(new
 ThreadStart(dosomwork1));
        Thread t2
=new Thread(new
 ThreadStart(dosomwork2));
        t1.Start();
        t2.Start();
        
if( s1 ==
 s2 )
            Console.WriteLine( 
"The same instance"
 );
        
else

            Console.WriteLine( 
"The different instance" );
    }

}
问题1:为什么直接执行显示The same instance,(将断点放在t1.Start();=......,且逐行执行的时候显示The different instance?我已经使用了double check lock啦。
问题2:有什么办法在单重判断的时候显示出The different instance吗?

posted @ 2006-04-21 16:39  Aldebaran's Home  阅读(500)  评论(0编辑  收藏  举报