一、立即加载/"饿汉模式"和延迟加载/"懒汉模式"
立即加载(又称饿汉模式):在使用类的时候已经将对象创建完毕,常见实现方法是直接new实例化
延迟加载(又称懒汉模式):在调用get()方法时实例才被创建,常见实现方法是在get()方法中进行new实例化
二、懒汉模式在多线程下的缺点及解决
缺点:可能会出现多个实例的问题。
解决:
1、声明synchronized关键字:
对get方法加上synchronized关键字即可保证同步运行,但效率太低。
2、尝试同步代码块
这个方法本质和synchronized一样,加锁同步执行,还是效率太低
3、针对某些重要的代码进行单独的同步。
效率提高了,但是没有解决问题,还是会有多个实例。
为什么不同步?因为只是对处理逻辑做了同步,但是进入处理逻辑的判断没有同步处理,还是会有问题的。
4、使用DCL双检查锁机制(大多数通用的机制)
即在第三种方式的基础上,在同步方法内,额外再做一次判断,判断通过执行相应代码,失败不执行。
三、单例模式的其他实现
3.1 使用静态内置类实现单例模式
这个和饿汉模式感觉没区别...不过不同的是:饿汉模式实在类初始化时直接创建,而静态内置类实在静态内部类被调用时实现。只是改变了实现的时间点,本质没什么区别。
静态内置类可以实现线程安全,但是如果遇到序列化对象时,使用默认方式运行得到的结果还是多例的。
3.2 序列化与反序列化的单例模式实现
静态内置类可以实现线程安全,但是如果遇到序列化对象时,使用默认方式运行得到的结果还是多例的。解决方法是:自己定义readResolve方法?
3.3 使用static代码块实现单例模式
这个和饿汉模式感觉没区别..只是一个是static对象,一个是static代码块
3.4使用enum枚举数据类型实现单例模式
枚举enum和静态代码块的特性相似,使用枚举类时,构造方法会被自动调用。
这种方式好像暴露了一些问题,在下一种方式中修复,具体是什么问题,其实我不理解...不理解什么单一原则呀..等