设计模式(4)单例模式

一.单例模式

程序中某个类只能有一个实例,如spring容器中的bean实例默认都是单例模式存在的

二.单例模式的好处

(1)避免对象的重复创建,减小时间和内存开销(2)避免操作多个对象导致的逻辑错误,可以全局统一控制

三.实现单例模式

    五种实现方案:饿汉模式,懒汉模式,双重校验锁,静态内部类,枚举

    1.饿汉模式
    
public class Singleton {
    //构造函数私有化
    private Singleton(){};
    private static Singleton instance = new Singleton();

    public Singleton getInstance(){
        return instance;
    }
}

        饿汉模式是在类加载的时候创建

        (1)好处:避免了线程同步问题

        (2)坏处:即使这个对象不会被用到也会被创建,浪费内存资源

    2.懒汉模式
public class Singleton1 {
    //构造函数私有化
    private Singleton1(){};
    private static Singleton1 instance = null;

    public Singleton1 getInstance(){
        if(instance == null){
            return instance;
        }
        return instance;
    }
}

        懒汉模式是实例在需要的时候才被创建

        (1)优点:按需创建,避免内存资源浪费

        (2)缺点:会出现线程安全问题,需要加锁解决

    3.双重校验锁-(对懒汉模式的改进)
public class Singleton2 {
    //构造函数私有化
    private Singleton2(){};
    private static volatile Singleton2 instance = null;

    public Singleton2 getInstance(){
        if(instance == null){
            synchronized (Singleton2.class){
                return new Singleton2();
            }
        }
        return instance;
    }
}

    其中的volatile是第二把锁,起到了禁止指令重排序优化的作用

    4.静态内部类-(对饿汉模式的改进)
public class Singleton3 {
    //构造函数私有化
    private Singleton3 (){};
    public static class Singleton{
        public static Singleton3 instance = new Singleton3();
    }

    public static Singleton3 getInstance(){
        return Singleton.instance;
    }
}

    与饿汉模式一样是通过类加载来实现的,因此不存在线程安全问题

    不同的是它在内部类加载这个实例,所以只要不使用这个内部类,JVM就不会加载这个单例,既实现延迟加载,又保证线程安全

    5.枚举
public enum Singleton4 {
    instance;
    public void whateverMethod(){}
}
    以上的四种方案都存在弊端,(1)需要额外的工作序列化,否则每次反序列化的结果都是一个新的实例

    (2)可通过反射机制强行调用私有构造器创建多个对象

    而这种方案解决了全部问题

    

猜你喜欢

转载自blog.csdn.net/qq_34645958/article/details/80850423
今日推荐