设计模式(单例设计模式)
单例设计模式:
1.什么是单例设计模式?
在整个应用中,我们保证我们所需要的实例只有一个。
2.如何实现?
在类加载的阶段就实例化一个静态变量实例,且将该类的构造函数设置为私有。则不能在创建其他的实例。这样就能保证只有在整个应用中只有一个实例。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
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