最经常使用的设计模式(单例模式)

  记得刚开始涉足程序的时候, 去笔试 ,发现有一个笔试题常常粗线,写一个单例模式的基本实现, 当时没研究设计模式也就不知为什么物,java

  到今日  , 才发现它已成为我平常开发最经常使用的一种设计模式。c++

  我写的全部设计模式的代码都会用java 呈现, 虽然第一个学习的是c++可是 最开始做为工做的是java,而且有点偏好javac#

  单例模式 , 意思就是 整个系统仅只有此类的一个实力, 固然这只是狭义的单例,常常看到变种的单例是容许,建立指定数量的实例的设计模式

  单例模式是一种建立型模式。 它是优化的一种策划, 避免重复建立销毁一个对象(建立销毁对象是有开销的), 有点像对象池的概念。安全

  

  我写博文  纯粹是对本身所了解的东西的一个回顾,  不保证权威性。  仅但愿 迷途的新手能在个人博文中 有所收获,我也尽可能 用我最简单的语言 去描述 我对 不少东西的理解、(这段话会在个人每个博文里面出现 由于 我不是一个看了书 作笔记的博客, 而是我进行思考的博客 ,固然也但愿大牛能够批评指正)多线程

 

  下面给出一个最简单的单例的实现函数

 1 public class HelloSingleton {
 2     
 3     private static HelloSingleton w_Instance = new HelloSingleton();
 4 
 5     //定义一个私有的构造函数,确保在该类的外部没法生成类的实例
 6     private HelloSingleton(){
 7         
 8     }
 9     
10     public static HelloSingleton getInst(){
11         return w_Instance;
12     }
13 }

这一种单例模式被成为饿汉模式, 其实意思就是开始的时候就实例好了 对象, 缺点是没有作到延迟加载 (延迟加载是一种优化策略,在须要的时候再去加载)这个用起来比较简便学习

 

而后下面是 另一种单例模式,懒汉模式优化

 

public class HelloSingleton {
    
    private static HelloSingleton w_Instance;

    //定义一个私有的构造函数,确保在该类的外部没法生成类的实例
    private HelloSingleton(){
        
    }
    
    public static HelloSingleton getInst(){
        if(w_Instance == null){
            w_Instance = new HelloSingleton();
        }
        return w_Instance;
    }
}
public class HelloSingleton {
    
    private static HelloSingleton w_Instance;

    //定义一个私有的构造函数,确保在该类的外部没法生成类的实例
    private HelloSingleton(){
        
    }
    
    public static HelloSingleton getInst(){
        if(w_Instance == null){
            w_Instance = new HelloSingleton();
        }
        return w_Instance;
    }
}

网上看到,或者大多数人都是如此写懒汉模式的, 这种写法在单线程环境下是安全的, 可是在多线程环境下 会形成生成多个实例的问题spa

好比现成A正在访问 getInst()方法 ,线程A读到w_Instance 为null ,建立该类对象并返回,线程B正好在此时也访问getInst方法,此时现成A构造的实例现成B没法看见,由于多线程环境中非同步代码快没法保证共享变量的可见性。因此该写法是有问题的, 调整为以下则不会在多线程环境下出现建立多个实例的问题。

 1 public class HelloSingleton {
 2     
 3     private static HelloSingleton w_Instance;
 4 
 5     //定义一个私有的构造函数,确保在该类的外部没法生成类的实例
 6     private HelloSingleton(){
 7         
 8     }
 9     
10     public static synchronized HelloSingleton getInst(){
11         if(w_Instance == null){
12             w_Instance = new HelloSingleton();
13         }
14         return w_Instance;
15     }
16 }
 1 public class HelloSingleton {
 2     
 3     private static HelloSingleton w_Instance;
 4 
 5     //定义一个私有的构造函数,确保在该类的外部没法生成类的实例
 6     private HelloSingleton(){
 7         
 8     }
 9     
10     public static synchronized HelloSingleton getInst(){
11         if(w_Instance == null){
12             w_Instance = new HelloSingleton();
13         }
14         return w_Instance;
15     }
16 }

java用synchronized保证同步代码快。 同步代码快 既保证 变量的原子性,也保证变量的可见性。

 

上面是最简单的两种单例的写法,可是为了扩展 , 仍是介绍一些 其余的 常见的单例的写法。

 

effective   java做者 推崇的 用枚举的方式实现的 singleton 

 

1 public enum HelloSingleton {
2     
3     Instance;
4     
5 }

额 你没有看错 就是这个样子的  , 起初 看到这个代码 , 我也很疑惑 , 这个是单例吗, 可是确实它也实现了单例 模式。 java的枚举不一样于 c++ , c#等语言, java的枚举是用对象实现的, 因此此枚举里 仅有一个对象

它的优势是这么介绍的 优势:不只能避免多线程同步问题,并且还能防止反序列化从新建立新的对象

 

第四种单例,采用静态内部类型, 个人同时  不少次 跟我讲 他以为java的内部类真的是很扯淡的设计, 不知道是干什么用的, 可是我我的感受java的内部类让java 语言用起来更灵活, 好比我 不想让别人使用的类 仅仅想在一个对象里面使用的类 ,就能够用private 定义一个 内部类 , 别人无须知道 内部实现。 更好的实现封装的思想,

代码示意图以下

 

 1 public class HelloSingleton {
 2      private static class SingletonHolder
 3      {
 4          private final static HelloSingleton w_Instance = new HelloSingleton();
 5      }
 6      
 7      private HelloSingleton(){
 8          
 9      }
10      
11      public static HelloSingleton getInst(){
12          return SingletonHolder.w_Instance;
13      }
14 }

 

此类型看起来比较晦涩  好像绕了不烧 , 这样写的好处是:加载时不会初始化静态变量INSTANCE,由于没有主动使用,达到延迟加载

 

还有一个类型就不介绍了 ,由于我的 基本没用到过,   感受本身最经常使用的就是第二种, 懒汉式 , 单例。

 

设计模式, 单例, 就是这么简单 。 

 

关于单例的变种你能够这么想 , 有的时候   你会想让单例 生成指定数量的 实例, 具体实现就是在 类里面加个 数量, 而后每次getInst 的时候去判断 是否达到最大数量, 若是达到就不在生成新的实例 ,若是没有,就生成新的实例返回, 好了 单例 就这么简单, 感受没什么好说的 就写到这里

相关文章
相关标签/搜索