设计模式--单例设计模式

设计模式是软件从业者长期以来总结的对特殊问题的解决方法,合理的使用设计模式可以很好的解决在开发中出现的问题。

单例模式 也是设计模式中最简单的一个设计模式,它的作用是保证一个类的对象在系统中唯一性。

单例模式解决了,对于频繁使用类创建对象的操作,这可以减少创建对象所需要的时间。对于频繁使用new创建对象来说,可以减少系统的使用频率,减轻GC的压力,缩短GC的处理时间。

单例模式内容

单例模式包含两个角色 单例类 和单例使用者

角色 作用
单例类 创建类对象 保证对象唯一性
类使用者 使用单例对象

他的基本结构如图1.1

                                                                            图 1.1 单例模式结构图

单例模式的核心就是 三私一公

私有化构造方法(这点非常重要,私有化构造方法可以防止通过new 创建对象)

私有化静态变量(用于存储类的实例化对象)

私有化克隆方法(避免通过公共方法获取实例后再通过clone克隆对象,这样就会产生出一个对象 这样就不能保证唯一了)

公共的静态方法(用于获取实例化对象)


/**
 * @author: yzjcsdn
 * @create 2018/4/17 14:56
 * @Description:
 */
public class SingletonTest1 {


    /**
     * 私有化构造方法
     */

    private SingletonTest1() {
        System.out.println("私有化构造方法");
    }

    /**
     * 私有化静态变量
     */
    private static SingletonTest1 singletonTest1 = new SingletonTest1();

    /**
     * 公共的获取对象的方法
     *
     * @return
     */
    public static SingletonTest1 getInstance() {
        return singletonTest1;
    }

    /**
     * 重写clone方法
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

上面的场景 并没有使用单例类 对象依然是被创建出来的 这样就为违背了单例的初衷因此需要改进上面的代买 如下


/**
 * @author: yzjcsdn
 * @create 2018/4/17 14:59
 * @Description:
 */
public class LazySingleton {


    private LazySingleton() {
        System.out.println("懒加载单例");
    }

   private  static LazySingleton lazySingleton = null;

    public static synchronized LazySingleton getInstance() {
        if (lazySingleton == null) {
            lazySingleton = new LazySingleton();
        }
        return lazySingleton;
    }
}

上面的部分引入了懒加载机制

此时要将获取实例的方法加上synchronize 对象锁,这样可以保证在多线程的情况下 获取的对象也是唯一性的,但是同样会出现一个问题性能问题

此外还可以使用内部类的方式创建单例对象。

/**
 * @author:yzjcsdn
 * @create 2018/4/17 16:27
 * @Description:
 */
public class ClazzSingtelon {


    private ClazzSingtelon(){
        System.out.println("内部类方式");
    }


    private static class ClazzSingtelonHolder{
        private static ClazzSingtelon clazzSingtelon = new ClazzSingtelon();
    }


    private static ClazzSingtelon getInstance(){
        return ClazzSingtelonHolder.clazzSingtelon;
    }
使用内部类的方式获取单例对象,当 ClazzSingtelon被加载时,其内部并不会被初始化,因此可以确保当ClazzSingtelon类被载入JVM时,并不会初始化单例类,而当getInstance()方法被调用时,才会加载ClazzSingtelonHolder,从而初始化instance。同同时,由于实例的简历是在类加载的时候完成,所以天生对多线程友好,getInstance()方法也不需要使用同步关键字。

通常情况下使用以上解决方法可以实现单例模式。但是仍然有例外情况,可能导致系统中生成多个实例,比如,在代码中通过单摄机制,强行调用单例的私有函数,生成多个单例,这些都是特殊性。

单例模式在Spirng中的应用

spring 初始化bean 默认是单例的 那么他的实现是怎样的呢?



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值