设计模式之单例模式

 

发车

单例模式(Singleton Pattern)是常用的一种设计模式,属于创建型模式。其定义的单例对象只允许一个实例存在。

应用场景

  • 对象使用频率高且实例不存在状态变化。

    • 数据库连接池

    • spring中bean的默认配置

    • struts1中的action

    • 工具类对象

    • 配置文件

    • ...

优点

  • 实例化一次,后续使用直接调用,节省对象频繁创建及销毁的开销,提高系统性能。

  • 只存在一个实例,节省内存空间。

实现单例的方式

  • 饿汉模式

    /**
    * @description 饿汉模式
    *             类加载时立即初始化创建单例对象
    *             优点:线程安全
    *             缺点:类加载初始化,不使用会浪费内存空间
    */
    public class Hungry {
       /**
        * 防止外部new对象
        */
       private Hungry() {}
       private static final Hungry HUNGRY = new Hungry();
       /**
        * 获取对象实例方法
        * @return
        */
       public static Hungry getInstance(){
           return HUNGRY;
      }
    }
  • 懒汉模式 非线程安全

    /**
    * @description 懒汉模式 非线程安全
    *             外部调用时实例化对象
    */
    public class LazyUnSafe {
       private LazyUnSafe() {}
       private static LazyUnSafe LAZYUNSAFE = null;
       /**
        * 存在线程安全问题
        */
       public static LazyUnSafe getInstance(){
           if(LAZYUNSAFE == null){
               LAZYUNSAFE = new LazyUnSafe();
          }
           return LAZYUNSAFE;
      }
    }
  • 懒汉模式 Double-Check

    /**
    * @description 懒汉模式 Double-Check
    *             外部调用时初始化创建对象
    *             线程安全;延迟加载;效率较高。
    */
    public class LazyDoubleCheck {
       private LazyDoubleCheck() {}
       private static LazyDoubleCheck LAZYDOUBLECHECK = null;

       /**
        * 获取实例方法
        */
       public static LazyDoubleCheck getInstance(){
           if(LAZYDOUBLECHECK == null){
               synchronized (LazyDoubleCheck.class) {
                   if (LAZYDOUBLECHECK == null) {
                       LAZYDOUBLECHECK = new LazyDoubleCheck();
                  }
              }
          }
           return LAZYDOUBLECHECK;
      }
    }
  • 静态内部类

    /**
    * @description 静态内部类
    *   特点:在外部类被调用的时候内部类才会被加载
    *   内部类在获取实例方法调用之前初始化,巧妙地避免了线程安全问题
    *   这种形式兼顾饿汉式的内存浪费,也兼顾synchronized性能问题
    *   完美地屏蔽了这两个缺点
    */
    public class LazyInnerClass {
       private LazyInnerClass(){}
       /**
        * 获取实例方法
        */
       public static LazyInnerClass getInstance(){
           return LazyHoder.LAZYINNERCLASS;
      }
       /**
        * 内部类,默认不加载
        */
       private static class LazyHoder{
           static {
               System.out.println("调用getInstance方法实例化LazyInnerClass对象时调用");
          }
           private static final LazyInnerClass LAZYINNERCLASS = new       LazyInnerClass();
      }
    }
  • 序列化

    /**
    * @description 序列化
    *             序列化的对象反序列化保证单例
    */
    public class Seriable implements Serializable {
       private Seriable(){}
       public static final Seriable SERIABLE  = new Seriable();
       public static Seriable getInstance(){
           return SERIABLE;
      }
       private  Object readResolve() throws ObjectStreamException {
           //返回指定的目标而非反序列化的目标
           return  SERIABLE;
      }
    }
posted @ 2018-11-11 17:24 share-lu 阅读(...) 评论(...) 编辑 收藏