饿汉模式也称直接加载。

立即加载就是使用类的时候已经将对象创建完毕,常见的实现方法就是直接new实例化。
立即加载是调用方法前,实例已经被创建了。

下面我们通过代码来了解此模式:

java懒加载如何获取数据 懒加载 java_加载


java懒加载如何获取数据 懒加载 java_延迟加载_02


运行结果:

java懒加载如何获取数据 懒加载 java_加载_03


输出的几个都是同一个值,说明对象是同一个,也就是实现了立即加载型单例设计模式。

懒汉模式也称延迟加载

延迟加载就是在调用get()方法时实例才被创建,常见的实现办法就是在get()方法中进行new实例化。
在调用方法时实例才被创建。

下面用代码来演示此模式:

java懒加载如何获取数据 懒加载 java_多线程_04


java懒加载如何获取数据 懒加载 java_加载_05


运行结果:

java懒加载如何获取数据 懒加载 java_延迟加载_06


此实验虽然取得一个对象的实例,但如果是在多线程的环境下,就会出现取出多个实例

的情况,与单例模式的初衷相违背。既然多个线程可以同时进入getInstance()方法,那么只需要对getInstance()方法声明synchronized关键字即可。

虽然使用synchronized进行方法或者代码块同步,但是对于效率还是比较低的。

下面针对某些重要的代码进行单独的同步:

同步代码块可以针对某些重要的代码进行单独的同步,而其他的代码则不需要同步。

这样在运行是效率可以完全得到很大的提升。

java懒加载如何获取数据 懒加载 java_java懒加载如何获取数据_07


java懒加载如何获取数据 懒加载 java_多线程_08


java懒加载如何获取数据 懒加载 java_延迟加载_09


此方法使同步synchronized语句块,只对实例化对象的关键diamagnetic进行同步,从语句的结构上来讲,运行的效率的确得到了提升。但如果遇到多线程的情况下还是无法得到同步一个实例对象的结果。

如何解决“饿汉模式”遇到多线程的情况呢?使用DCL双检查锁机制:

使用DCL双检查锁机制来实现多线程环境中的延迟加载单例设计模式。

实验示例:

修改getInstance()方法:

java懒加载如何获取数据 懒加载 java_多线程_10


java懒加载如何获取数据 懒加载 java_加载_11


此时成功解决饿汉模式遇到多线程的问题。