饿汉模式也称直接加载。
立即加载就是使用类的时候已经将对象创建完毕,常见的实现方法就是直接new实例化。
立即加载是调用方法前,实例已经被创建了。
下面我们通过代码来了解此模式:
运行结果:
输出的几个都是同一个值,说明对象是同一个,也就是实现了立即加载型单例设计模式。
懒汉模式也称延迟加载
延迟加载就是在调用get()方法时实例才被创建,常见的实现办法就是在get()方法中进行new实例化。
在调用方法时实例才被创建。
下面用代码来演示此模式:
运行结果:
此实验虽然取得一个对象的实例,但如果是在多线程的环境下,就会出现取出多个实例
的情况,与单例模式的初衷相违背。既然多个线程可以同时进入getInstance()方法,那么只需要对getInstance()方法声明synchronized关键字即可。
虽然使用synchronized进行方法或者代码块同步,但是对于效率还是比较低的。
下面针对某些重要的代码进行单独的同步:
同步代码块可以针对某些重要的代码进行单独的同步,而其他的代码则不需要同步。
这样在运行是效率可以完全得到很大的提升。
此方法使同步synchronized语句块,只对实例化对象的关键diamagnetic进行同步,从语句的结构上来讲,运行的效率的确得到了提升。但如果遇到多线程的情况下还是无法得到同步一个实例对象的结果。
如何解决“饿汉模式”遇到多线程的情况呢?使用DCL双检查锁机制:
使用DCL双检查锁机制来实现多线程环境中的延迟加载单例设计模式。
实验示例:
修改getInstance()方法:
此时成功解决饿汉模式遇到多线程的问题。