设计模式-单例

单例模式是我们在项目中最常用的模式,有很多种写法,在不同的应用场景中,不同的写法可能会产生不同的问题,在此做个整理记录。

简单单例模式的实现:a、将构造方法私有化;b、定义一个静态的私有变量来实例化类对象;c、对外提供一个静态的方法入口,返回已经实例化的类对象。

1、最初的单例写法:

public class SimpleSingleton {
    private static SimpleSingleton singleton = new SimpleSingleton();
    private SimpleSingleton(){
        System.out.println("init.......");
    }
    public static SimpleSingleton getInstance(){
        return singleton;
    }
}

这种实现是线程安全的,多个线程进行访问时不会实例化多个对象,因为static属性只会被初始化一次,缺点是无论该实例是否用到都会被初始化,无形中增大了开销,为了解决这种浪费资源的问题,就有了下面的单例实现:


2、大家熟称的饿汉试实现:

public class SimpleSingleton {
    private static SimpleSingleton singleton = null;
    private SimpleSingleton(){
        System.out.println("init.......");
    }
    public static SimpleSingleton getInstance(){
        if(singleton==null){
            singleton = new SimpleSingleton();
        }
        return singleton;
    }
}

这种实现保证只有在调用该类的时候对象才被初始化,但是缺点是线程不安全,当多个线程同时访问的时候(多个线程同时访问并且判断为null),极可能实例化出多个对象,为了解决这种实例化多个对象的问题。继续优化getInstance()方法添加同步,但是这种虽然解决了线程安全问题,但是降低了性能。


3、double-cheched-locking模式

public class SimpleSingleton {
    private volatile static SimpleSingleton singleton = null;
    private SimpleSingleton(){
        System.out.println("init.......");
    }
    public static  SimpleSingleton getInstance(){
        if(singleton==null){
            synchronized (SimpleSingleton.class) {
                if(singleton==null) {//防止两个线程同时经过第一个判断
                    singleton = new SimpleSingleton();
                }
            }
        }
        return singleton;
    }
}
经过这么多的优化终于实现了线程安全又能实现懒加载的单例模式,其实还有一种个人比较喜欢,认为比较完美的,代码整洁的实现方式,使用内部类实现


4、完美的单例实现:

public class InnerClassSingleton {
    private InnerClassSingleton(){
        System.out.println("init.......");
    }
    public static class InnerClass{
        public final static InnerClassSingleton instance = new InnerClassSingleton();
    }
    public static InnerClassSingleton getInstance(){
        return InnerClass.instance;
    }
}
这种方式同样利用了classloder的机制来保证初始化instance时只有一个线程,而这种方式是InnerClassSingleton类被装载了,instance不一定被初始化。因为InnerClass类没有被主动使用,只有显示通过调用getInstance方法时,才会显示装载InnerClass类,从而实例化instance。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值