首页 > 代码库 > 设计模式(四) : 创建型模式--单例模式

设计模式(四) : 创建型模式--单例模式

单例模式的话,类图上来看是最简单的设计模式,就是一个类只能有一个自己的实例。

单例模式通常来说我们就有Lazy loading的和不是Lazy loading的。《java与模式》里面的关于这两种的类图,:

可以看到一个是现开始就实例话的,这样的话不符合我们的lazy loading,还有一种是在getinstance方法里头去new的,这样的话会有线程安全的问题,我们提供了双重检查锁。

下面看示意代碼︰

1. 静态初始化:

package com.javadesignpattern.Singleton;

public class SingletonLazyLoading {
    
    private static SingletonLazyLoading instance = new SingletonLazyLoading();
    
    private SingletonLazyLoading(){
        
    }
    
    public static SingletonLazyLoading getInstance(){
        return instance;
    }
    
}

2.双重检察锁

package com.javadesignpattern.Singleton;

public class SingletonNonLazyLoading {
    
    private static volatile SingletonNonLazyLoading instance;
    
    private SingletonNonLazyLoading(){
        
    }
    
    public static SingletonNonLazyLoading getInstance(){
        synchronized(SingletonNonLazyLoading.class){
            if(instance == null){
                instance =  new SingletonNonLazyLoading();
            }
        }        
        return instance;
    }
    

}

3.静态内部类

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.javadesignpattern.Singleton;
 
public class SingletonStaticInnerClass {
     
     
    private SingletonStaticInnerClass(){
         
    }
     
    static class InnerClass{
        private static SingletonStaticInnerClass instance = new SingletonStaticInnerClass();
    }
     
    public static SingletonStaticInnerClass getInstance(){
        return InnerClass.instance;
    }
 
}

 4. 枚举

package com.citi.designpattern.singleton;

public class SingletonEnum {
    
    public static void main(String[] args){
        System.out.println(Singleton.INSTANCE == Singleton.getInstance());
    }
    

}

enum Singleton { INSTANCE;
    
    public static Singleton getInstance(){
        return INSTANCE;
    }
}

测试代码:

package com.javadesignpattern.Singleton;


public class TestMain {
    
    public static void main(String[] args){
        //1.LazyLoading
        /*SingletonLazyLoading singleton1 = SingletonLazyLoading.getInstance();
        SingletonLazyLoading singleton2 = SingletonLazyLoading.getInstance();
        
        System.out.println(singleton1 == singleton2);*/
        
        //2.No-LazyLoading
        SingletonNonLazyLoading instance1 = SingletonNonLazyLoading.getInstance();
        SingletonNonLazyLoading instance2 = SingletonNonLazyLoading.getInstance();
        System.out.println(instance1 == instance2);
        
        //3. static inner class
        SingletonStaticInnerClass sInstance1 = SingletonStaticInnerClass.getInstance();
        SingletonStaticInnerClass sInstance2 = SingletonStaticInnerClass.getInstance();
        System.out.println(sInstance1 == sInstance2);
        
        //4. Enum
        System.out.println(Singleton.INSTANCE == Singleton.getInstance());
        
    }

}


enum Singleton { INSTANCE;
    
    public static Singleton getInstance(){
        return INSTANCE;
    }
}

枚举的方式始effective java推荐的。序列化的时候能保证单例,而且比较简单。当然别的方式的序列化可以用重写 readreslove 来保证单例。

//readResolve to prevent another instance of Singleton
    private Object readResolve(){
        return INSTANCE;
    }