博客信息

设计模式之单例模式

0
发布时间:『 2016-12-09 09:48』  博客类别:设计模式  阅读(560) 评论()

设计模式之单例模式:

      单例模式是我们使用设计模式最多的一种,也是最常见的一种,那么我们看一下常见的集中编写单例模式的demo,以及各种demo的问题:

      1:懒汉式(在需要初始化的时候在创建)

   public class CreateSingleTonForFull {
    /**
     * 传说中的饱汉式
     */
    private static CreateSingleTonForFull createSingleTonForFull=null;
    public CreateSingleTonForFull getInstance(){
        createSingleTonForFull=new CreateSingleTonForFull();
        return createSingleTonForFull;
    }
   }

    2:饿汉式(代码初始化时就创建实例)

   public class CreateSingleTonForHungary {
    /***
     * 传说中的饿汉式
     */
    private static CreateSingleTonForHungary createSingleTonForHungary=
            new CreateSingleTonForHungary();
    public CreateSingleTonForHungary getInstance(){
        return createSingleTonForHungary;
    }
    }

   说明:我们在申明变量的时候是把变量写作private,这样就防止了类被继承,重写初始化方法,也保证了只有通过这种方式进行初始化

   3:双重检查(不推荐)

public class SingleTonDoubleCheck {
    private static SingleTonDoubleCheck singleton=null;
    public SingleTonDoubleCheck getInstance(){
        if(singleton==null){
             synchronized (SingleTonDoubleCheck.class){
                 if(singleton==null){
                     singleton=new SingleTonDoubleCheck();
                 }
             }
        }
        return singleton;
    }
}
  /***这样写的问题-------
     * 首先解释一下这个代码的分解:
     * 1:分配内存
     * 2:初始化对象
     * 3:把对象的引用地址指向内存地址
     * 存在的问题就是初始化对象的时候初始化的时间很长,就会发生指令重排序。
     * 在导致第三步失败
     * 解决的方式如下:SingleTonDoubleCheck2
     */

双重检查改变:

   public class SingleTonDoubleCheck2 {
    /****
     * 把初始化变量修饰成一个内存可见的量,这样就不会发生指令重排序
     */
  private volatile  static SingleTonDoubleCheck2 singleTonDoubleCheck2=null;
  public SingleTonDoubleCheck2 getInstance(){
      if(singleTonDoubleCheck2==null){
          synchronized (SingleTonDoubleCheck2.class){
              singleTonDoubleCheck2=new SingleTonDoubleCheck2();
          }
      }
      return singleTonDoubleCheck2;
  }
}

为什么把变量写成volatile,就是为了防止指令重排序,详细请戳:volatile的用法

4:用枚举实现单例(effectivejava推荐)

     枚举类型适合初始化数据单例,比如创建时就提供一堆数据这样;如下:

public enum CreateSingleByEnum {
    singletoninstance;
    private Map<String,String> allCities=new ConcurrentHashMap<String,String>();
    private CreateSingleByEnum(){
        init();
    }
    private void init(){
        getInstance();
    }

    public void getInstance(){
        /**
         * do something
         */
        System.out.println("create singleton is ok");
        allCities.put("1","beijin");
    }

    public Map<String, String> getAllCities() {
        return allCities;
    }

    public void setAllCities(Map<String, String> allCities) {
        this.allCities = allCities;
    }
}

这个单例就是我在创建时就得给map中put数据,然后看一下调用方式:

1482754556798074025.jpg

关键字:   单例模式     单例模式双重检查     创建单例  
Copyright © 2012-2017 yinbin.lan 版权所有   京ICP备16047123号