设计模式(单例设计模式)

单例设计模式:

1.什么是单例设计模式?

  在整个应用中,我们保证我们所需要的实例只有一个。

2.如何实现?

  在类加载的阶段就实例化一个静态变量实例,且将该类的构造函数设置为私有。则不能在创建其他的实例。这样就能保证只有在整个应用中只有一个实例。

 1 public class SingleTest {
 2     public static final SingleTest instance = new SingleTest();
 3 
 4     private SingleTest() {
 5     }
 6     //用于获取该实例的静态方法
 7     public static SingleTest getInstance(){
 8         return instance;
 9     }
10 }
View Code

3.优化

  在上述代码中,在该类加载的阶段,该实例就会被创建。然后在整个应用过程中,可能都不会用到该单例instance。该方法浪费内存。

通过在网上资料的查询,了解到使用lazy loaded (延迟加载)。代码如下

 1 public class SingleTest {
 2     public static SingleTest instance = null;
 3 
 4     private SingleTest() {
 5     }
 6 
 7     public static SingleTest getInstance(){
 8         if (instance==null){
 9             instance = new SingleTest();
10         }
11         return instance;
12     }
13 }

  在使用getInstance方式时才判断是否为null,为null则初始化。

4.在3中的代码,虽然节省下了内存,但是在多线程并发下,会出现同时破坏单例模式。

  线程A:执行完毕第8行的代码后,判断为null。然后切换时间片。

  线程B:执行到完毕第8行的代码后,判断为null(因为线程A还没有创建对象)。然后切换时间片。

  线程A:创建一个实例

  线程B:创建一个实例

所以会出现两个实例,破坏单例模式。

这里有一个贼棒的代码,来处理该情况

 1 public class SingleTest {
 2     public static SingleTest instance = null;
 3 
 4     //私有的构造函数。这样就不能新增实例
 5     private SingleTest() {
 6     }
 7 
 8     public static SingleTest getInstance(){
 9         //判断是否为Null
10         if (instance==null){
11             //加锁。
12             synchronized (SingleTest.class){
13                 //判断是否为null。
14                 if (instance==null)
15                     instance = new SingleTest();
16             }
17         }
18         return instance;
19     }
20 }

 这样在获取实例的时候,先判断是不是为null,是为null,再进入里面带有锁的判断。加锁保证只会有一个实例被创建

 

 

参考链接:https://bbs.csdn.net/topics/391840031

posted @ 2018-07-19 09:15  兼爱子墨  阅读(127)  评论(0编辑  收藏  举报