GOF23---谈谈单例模式

单例模式的核心竞争力在于:保证了一个类只有一个实例,节省系统资源。

单例模式的应用场景在于:当我们创建一个类的实例的时候要消耗很多的系统资源,或者我们要通过读取配置文件来获得一个类的实例的时候,我们就可以使用单例模式,这里可以减少每次重新创建一个新对象的资源消耗。比如我们javaee中的servlet编程中,Application和每一个servlet类都是单例的,我们在数据库连接池的设计也是一般采用单例模式,spring中每个bean默认是单例的,springMVC框架中的控制器对象等等。

单例模式的实现方式:

1.饿汉式:一上来就创建静态属性指向一个实例对象的引用,私有化构造函数,提供一个供外界获得对象实例引用的接口。代码如下:

public class SingletonDemo1 implements Serializable{
    private static final SingletonDemo1 INSTANCE = new SingletonDemo1();//类一初始化,就获得一个对象引用

    private SingletonDemo1() { };//核心点:私有化构造函数
    public static SingletonDemo1 getInstance() {   //外界获得对象引用的接口
        return INSTANCE;
    }
}

其优点在于:线程安全(并发问题是在于程序员访问时候发生,类加载静态方法和静态属性时,没有程序员可以访问,天然的优势),调用效率高;

其缺点在于:类一初始化就创建一个对象,但是程序员可能只是通过类来调用其他静态方法,根本不需要改对象,造成内存浪费。也就是说:不能延时加载对象。

 

2.懒汉式:针对饿汉式的不能延时加载,进行修改,提供了延时加载对象的功能。代码如下:

public class SingletonDemo2 {

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

}

使用了synchronized来锁住这个方法的访问对象,可避免同步并发的问题。

其优点在于:提供延时加载,可以避免内存浪费,线程也是安全的;

其缺点在于:引入锁,导致效率会降低。

3.使用静态内部类:通过jvm的在初始化类时不会自动加载静态内部类的特性,也可以实现天然的线程安全。代码如下:

public class SingletonDemo3 {
    
    private static class
Single{
        private static SingletonDemo3 instance = new SingletonDemo3();
    } ;

    private SingletonDemo3() {
    };

    public static SingletonDemo3 getInstance() {
        return
Single.instance;
    }
}

其优势在于:提供延时加载,能避免内存的浪费,在实际工作中一般采用这种方式。

以上3种实现单例的方式都有一个共同的特点:私有化构造函数。这样也暴露一个问题:通过反射和反序列化强行创建新的对象实例。所以我们介绍下第四种

4.枚举实现单例:利用枚举本身的天然特性--枚举就是单例模式,而枚举由于jvm根本上提供保障,可以避免反射和反序列化的漏洞。代码如下:

public enum SingletonDemo4 {
    INSTANCE;
    }

单例模式的使用小结:

如果类创建实例的资源消耗多,那么就需要延时加载,静态内部类方式由于懒汉式;如果不需要延时加载,枚举优于饿汉式。

 

 

 

 

转载于:https://my.oschina.net/u/2931572/blog/755278

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值