设计模式之单例模式

本文深入探讨单例模式的原理和应用场景,包括数据库连接池、工具类等,详细讲解了饿汉模式、懒汉模式及其线程安全变种、静态内部类和序列化四种实现方式,帮助读者理解并掌握单例模式的正确应用。
 
发车

单例模式(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;
      }
    }

转载于:https://www.cnblogs.com/share-lu/p/9942682.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值