单例设计模式

(一)概述

1、模式:生产实践中,积累的经验、办事情的套路

2、设计模式:在设计类型、设计接口、设计方法、完成某些架构的时候使用的套路,就是

设计模式。

软件开发过程中,有23种设计模式,在不同的场景下、在不同的需求中,使用的是不同

的设计模式。

3、单例模式:

在当前系统中,某个类型的对象,最多只能有一个,就需要使用单例设计模式

4、单例模式的设计原则:

1、构造方法私有化,不能让外界随意创建对象

2、在类中创建好该类对象

3、在类中,给外界提供获取该对象的公有方式

(二)饿汉式

1、在加载类的同时,就要初始化静态成员变量,所以就同时将该类对象创建出来了

2、饿汉式:一有机会,马上就吃,不去等待。(一旦加载类型,马上创建对象)

/**
 * 饿汉式:类只要一加载对象就会创建完毕,就像一个很饿的人,一给东西就吃
 */
class SingletonHungry {

    //1.构造方法私有化,限制外界创建对象
    private SingletonHungry() {}

    //2.提前创建好一个对象
    private static SingletonHungry sh = new SingletonHungry();

    //3.对外提供公开的访问方式
    public static SingletonHungry getInstance() {
        return sh;
    }
}

(三)懒汉式

1、在加载类的时候,不同时创建该类对象,等到需要获取这个对象时,才去创建这个对象

2、懒汉式:不着急、能不创建的时候,就不创建,能拖就拖

3、注意事项:

1、只有在sl == null的时候,才会创建对象

2、sl的判断和sl的赋值,不希望分离开,否则在多线程环境下,会出现多个对象的状

态,所以sl的判断和sl的赋值,需要放到一个同步代码块中。

3、同步代码块的效率非常低,不是每次获取对象的时候,都需要判断锁对象,所有在sl

为null的时候, 才应该判断锁对象,因此在外层需要嵌套一个if判断,判断sl是否为null

/**
 * 懒汉式:能拖就拖,能不创建就不创建,是在没有办法的时候再去做
 */
class SingletonLazy {

    //1.构造方法私有化,限制外界创建对象
    private SingletonLazy() {}

    //2.提前在类中创建对象
    private static SingletonLazy sl;

    //3.对外提供获取方式
    public static SingletonLazy getInstance() {//A  B
        //注意事项:内外层的if都不能省略,如果省略外层,降低效率;如果省略内层,依然会出现多线程安全问题
        //3.频繁获取锁对象,容易降低系统效率,为了提升效率,先判断对象是否有,如果没有再创建,有就直接跳过
        if (sl == null) {
            //2.在多线程下,针对于1,可能会出现创建多个对象的情况,所以为了保证多线程安全,加上同步
            synchronized (SingletonLazy.class) {
                //1.判断如果当前对象不存在,再去创建对象
                if (sl == null) {
                    sl = new SingletonLazy();
                }
            }
        }

        return sl;
    }
}

(四)饿汉式的另一种形式

1、也是随着类的加载,而创建对象(也算是饿汉式的一种)

2、不再提供访问私有成员变量的方法

3、指向对象的引用设置为公有的访问权限,但是这样可能会被外界修改,因此在引用前面

加上final,外界只能访问该变量,不能修改该变量的值。

class SingletonHungry2 {
    //1.构造方法私有化,限制外界创建对象
    private SingletonHungry2() {}

    //2.提前创建好对象
    public static final SingletonHungry2 sh = new SingletonHungry2();
}
原文地址:https://www.cnblogs.com/conglingkaishi/p/15128472.html