重温设计模式之单例模式

内容大概引用一位博友的描述,说的很清楚:

首先,单例模式是对象的创建模式之一,此外还包括工厂模式。单例模式的三个特点:
1,该类只有一个实例
2,该类自行创建该实例(在该类内部创建自身的实例对象)
3,向整个系统公开这个实例接口

class Singleton { 
      
    //私有,静态的类自身实例 
    private static Singleton instance = new Singleton(); 
      
    //私有的构造子(构造器,构造函数,构造方法) 
    private Singleton(){} 
      
    //公开,静态的工厂方法 
    public static Singleton getInstance() { 
        return instance; 
    } 
} 

使用时:

Singleton obj = Singleton.getInstance(); 

这个单例类在自身被加载时instance会被实例化,即便加载器是静态的。因此,对于资源密集,配置开销较大的单体更合理的做法是将实例化(new)推迟到使用它的时候。即惰性加载(Lazy loading),它常用于那些必须加载大量数据的单体。修改下

class LazySingleton { 
    //初始为null,暂不实例化 
    private static LazySingleton instance = null; 
      
    //私有的构造子(构造器,构造函数,构造方法) 
    private LazySingleton(){} 
      
    //公开,静态的工厂方法,需要使用时才去创建该单体 
    public static LazySingleton getInstance() { 
        if( instance == null ) { 
            instance = new LazySingleton(); 
        } 
        return instance; 
    }    
} 

使用方式同上。

上面这种方式在使用时仍然有缺陷,那就是线程安全问题,所以再次修改如下:

public sealed class Singleton
 2{
 3    static Singleton instance=null;
 4    static readonly object padlock = new object();
 5
 6    Singleton()
 7    {
 8    }
 9
10    public static Singleton Instance
11    {
12        get
13        {
14            lock (padlock)
15            {
16                if (instance==null)
17                {
18                    instance = new Singleton();
19                }
20                return instance;
21            }
22        }
23    }
24}

这种方式的实现对于线程来说是安全的。我们首先创建了一个进程辅助对象,线程在进入时先对辅助对象加锁然后再检测对象是否被创建,这样可以确保只有一个实例被创建,因为在同一个时刻加了锁的那部分程序只有一个线程可以进入。这种情况下,对象实例由最先进入的那个线程创建,后来的线程在进入时(instence == null)为假,不会再去创建对象实例了。但是这种实现方式增加了额外的开销,损失了性能。

内容参考如下博客:

http://www.cnblogs.com/snandy/archive/2011/04/07/2007717.html

http://terrylee.cnblogs.com/archive/2005/12/09/293509.html

原文地址:https://www.cnblogs.com/jangwewe/p/3016848.html