看代码,第一行定义了一个final Instance,
第二行,使用private 修饰Mgr01(),表明这个类不能new 对象,只能使用getInstance的方法获取
第三行就是 使用getInstance方法的构造方法,始终是返回INSTANCE,就是这一个对象,所以这是单例
由于单例有一个缺点,就是在类进入内存时,所有的对象都会被实例化出来(类装载就完成实例化),于是出现了懒汉式
lazy loading
使用 if 判断INSTANCE是否是空,是空就创建,不是空就直接返回
然后懒汉式 又有线程不安全的问题,就是 在判断实例是否等于空的时候,可能有其他线程进来,同时判断
为了解决线程不安全的问题,我们又想到了 加锁,最直接的方式就是 synchronized
然后又出现新的问题,加锁会导致 效率降低,有没有其他的办法呢?在加锁的同时 提高效率呢?
小猪同学给出了一种方案:
这种方案,在if判断的时候,就可能有两个线程同时通过,这里加锁的目的,只不过是让两个线程创建对象的顺序变了一下,还是会创建出不同的对象的,小猪策略被pass
小明提出一种双重锁的策略:
这种写法实验证明可行,小明真聪明
马老师这个时候也提出了自己的写法,完美的写法
静态内部类的方式
自己理解是 将饿汉式 进行优化,怎么说呢?饿汉式不是在类加载的时候就将对象实例化了吗?我们就想把这个对象换一个存储位置,不让它在类加载的时候就实例化,发现放在 内部类里面,这就不会自动直接加载,而是在调用内部类的时候,这个对象才会被实例化
就是将对象实例化的操作放在了Mgr07Holder类里面了,在外面调用getInstance获取对象的时候,返回内部类方法,才会去该内部类中获取new对象,听懂掌声!!!!
补充:虚拟机在加载class的时候,它只会加载一次,然后class里面内部的class也是只会加载一次
这个时候 java的作者看到马老师写的这么完美的写法,自己脸上挂不住,然后java的设计者之一,Joshua,也写出了一种很牛方案: