前言
前面我们介绍了单例模式的饿汉模式,其实饿汉式很好理解,形象的记忆就是不管怎么样,先把内存吃掉再说。本着贪多嚼不烂的原则,我们今天来看看懒汉式,这个懒汉式就有三种不同的形式。当然还是理解为主。
懒汉式(线程不安全)
在同一个线程中运行,这个方法没有问题。我们先看代码,后面再来看看这个懒汉式的优缺点。
1 | package com.yubulang.type03; |
2 | |
3 | public class Singleton { |
4 | private Singleton() { |
5 | } |
6 | |
7 | private static Singleton instance; |
8 | |
9 | // 提供一个静态的公有方法,当使用到该方法时,才去创建instance |
10 | // 懒汉式1 这个因为懒,懒得线程都不安全了 |
11 | public static Singleton getInstance() { |
12 | if (instance == null) { |
13 | instance = new Singleton(); |
14 | } |
15 | |
16 | return instance; |
17 | } |
18 | } |
优缺点:
- 起到了
Lazy Loading
效果,但是只能在单线程下使用。 - 如果在多线程下,一个线程进入了 if (instance == null) 判断语句块,还未来得及往下执行,另一个进程也通过了这个判断语句,这时便会产生多个实例。所以在多线程的情况下不要使用这种方式
- 结论:在实际开发中,不要使用这种模式
懒汉式(线程安全,同步方法)
为了得到一个线程安全的代码,我们加入了 synchronized
代码,但是这个方法有利有弊。
1 | package com.yubulang.type04; |
2 | |
3 | public class Singleton { |
4 | private Singleton() { |
5 | } |
6 | |
7 | private static Singleton instance; |
8 | |
9 | // 提供一个静态的公有方法,当使用到该方法时,才去创建instance |
10 | // 懒汉式2 为了解决线程安全问题,我们加入同步代码 |
11 | public static synchronized Singleton getInstance() { |
12 | if (instance == null) { |
13 | instance = new Singleton(); |
14 | } |
15 | |
16 | return instance; |
17 | } |
18 | } |
优缺点:
- 解决了线程不安全问题
- 效率太低了,每个线程在想获得类的实例时候,执行 getInstance() 方法都要进行同步。而其实这个方法只执行一次实例化代码就够了,后面的想获得该类实例,直接return就行了。方法进行同步效率太低。
- 结论:在实际开发中,不推荐使用这种方法
懒汉式(线程安全,同步代码块)
其实这种写法,是白给,因为和第一个中模式一样,我们先看代码再看总结
1 | package com.yubulang.type05; |
2 | |
3 | public class Singleton { |
4 | private Singleton() { |
5 | } |
6 | |
7 | private static Singleton instance; |
8 | |
9 | // 提供一个静态的公有方法,当使用到该方法时,才去创建instance |
10 | // 懒汉式3 为了解决线程安全问题,我们加入同步代码 |
11 | public static Singleton getInstance() { |
12 | if (instance == null) { |
13 | synchronized (Singleton.class) { |
14 | instance = new Singleton(); |
15 | } |
16 | } |
17 | |
18 | return instance; |
19 | } |
20 | } |
优缺点:
- 这种方式,本意是想引出下面的改进版本,因为前面同步方法效率太低,改为同步产生实例化的代码块
- 但是这种同步方式并不能起到线程同步的作用。跟第三种实现方式遇到的情景一致,假如一个线程进入了 if (instance == null) 判断语句块,还未来得及往下执行,另一个进程也通过了这个判断语句,这时便会产生多个实例。所以在多线程的情况下不要使用这种方式
- 结论:在实际开发中,不要使用这种模式
总结
其实懒汉式大叫了解一下就好了。实际开发中并不怎么使用,让它存在主要是为了引出下面的的一些方法。PEACE!!!