单例模式

2020-05-19  本文已影响0人  水煮鱼又失败了

目录

[TOC]

1. 饿汉模式

在类加载的时候,将实例instance创建出来。

1.1 优点

简单,可靠。

1.2 缺点

在类加载的时候,加载单例实例,如实例比较复杂,将大大增加类加载过程中JVM的负担。

1.3 代码

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

1.4 用法

public class Singleton {
    
    private static Singleton instance;
    
    private String paramA;
    private String paramB;
    
    static {
        instance=new Singleton();
        instance.paramA="A val";
        instance.paramB="B val";
    }
    
    private void Singleton(){
    }
    
    public static Singleton getInstance(){
        return instance;
    }
}

2. 懒汉模式(线程安全)

在需要的时候,再去创建实例。

2.1 代码

public class Singleton {
    private static Singleton instance;
    
    private void Singleton(){
    }
    
    public static synchronized Singleton getInstance(){
        if(instance==null){
            instance=new Singleton();
        }
        return instance;
    }
}

3. 懒汉模式(线程安全+双重判定)

关键字volatile修饰判断的属性,防止指令重排,即防止对象的地址分配,在对象的属性初始化之前执行

3.1 代码

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

4. 静态内部类模式

懒加载,并且是线程安全的

4.1 代码

public class Singleton {
    private Singleton(){
    }
    
    private static class SingletonHolder{
        private static Singleton instance=new Singleton();
    }
    
    public static Singleton getInstance(){
        return SingletonHolder.instance;
    }
}

5. 枚举模式

effective java中说最佳的单例模式是枚举模式。

线程安全,且无需担心反射方式初始化对象。

5.1 代码

public enum Singleton {
    
    INSTANCE;
 
    public void doMethod(){
        //......
    }
}

5.2 应用

public enum Singleton {
    
    INSTANCE("A val");
    
    private String paramA;
    private String paramB;
    
    Singleton(String paramA){
        this.paramA=paramA;
    }
    
    public void setParamB(String paramB){
        this.paramB=paramB;
    }
    
    public void doMethod(){
        System.out.println(String.valueOf(paramA)+"_"+String.valueOf(paramB));
    }
}

调用方式如下:

public static void main(String[] args) {
    Singleton singleton=Singleton.INSTANCE;
    singleton.setParamB("B val");
    singleton.doMethod();
}

输出以下内容:

A val_B val

上一篇下一篇

猜你喜欢

热点阅读