设计模式(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.双重校验锁-(对懒汉模式的改进)
    如果没有第二次校验锁,也可能产生懒汉模式带来的问题,多个线程同时进入第一个if,这样会导致创建多个instance

    

public class Singleton2 {
    private Singleton2(){}
    private static volatile Singleton2 instance;

    private Singleton2 getSingleton(){
        if(instance == null){
            synchronized (Singleton2.class){
                if(instance == null)
                    instance = 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)可通过反射机制强行调用私有构造器创建多个对象

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

    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值