JAVA基础(五)单例模式

网上盛传单例模式有7种,大致分为懒汉式和饿汉式。其他都是他俩的变种。这里重点分析下二次枷锁的懒汉式单例模式

public class Singleton {
    private volatile static Singleton mInstance;//注意点1
    private Singleton(){}//注意点2
    public static Singleton getInstance(){//注意点3
        if(mInstance == null){
            synchronized(this){
                if(mInstance == null){//注意点4
                    mInstance = new Singleton();
                }
            }
        }
        return mInstance;
    }
}
  • 注意点1:将mInstance变量定义为volatile。是为了让其他线程可见。volatile的作用是给变量设置内存屏障。当本线程的变量在对此变量进行读写操作时,会锁住CPU总线,完成后会刷新主内存,这样其他线程操作此变量时都是使用的最新的值。保证了变量同步。如果这里没有volatile修饰符,另一个线程可能在变量正在初始化但还未完成时引用到它。使得得到的mInstance实例数据不完整。通过volatile就可以保证happens-before关系,也就是所有对变量的写操作都会在读操作之前发生。个人觉得volatile是为了保证变量完整性才存在的。
  • 注意点2:将构造方法定义为private类型,保证外部接口访问不到
  • 注意点3:getInstance()为static类型
  • 注意点4:双重判空的原因是因为第一次判空后,会对this进行加锁操作,此操作会耗时,如果在枷锁的时候,另外一个线程已经将mInstance实例创建出来了,这儿又创建一个,不符合单例模式只有一个对象的原则。

以上就是对双重加锁单例模式的理解。以下是其他情况,有些没写大同小异

    //饿汉式1
    static class Singleton1{
        private static Singleton1 mInstance = new Singleton1();
        private Singleton1(){}
        public static  Singleton1 getInstance(){
            return mInstance;
        }

    }
    //饿汉式2
    static class Singleton2{
        private  static Singleton2 mInstance ;
        static{
            mInstance = new Singleton2();
        }
        private Singleton2(){}
        public static Singleton2 getInstance(){
            return mInstance;
        }

    }

    //静态内部类方式,在被使用的时候才会去加载静态内部类
    //懒汉式
    static class Singleton3{
        private static class SingletonHold {
            private static final Singleton3 INSTANCE = new Singleton3();
        }
        private Singleton3(){}
        private static Singleton3 getInstance(){
            return SingletonHold.INSTANCE;
        }
    }

对于上面这种使用静态内部类的方法,我们还能学习到静态内部类的加载时机。和静态变量不大一样,静态变量在整个类加载进来时就已经完成了初始化操作。而对于静态内部类,只有当该类被调用时才回去加载。所以这种也是懒汉式加载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值