4、单例模式(Singleton Pattern)

单例模式是保证系统实例唯一性的重要手段。单例模式首先通过将类的实例化方法私有化来防止程序通过其他方式创建该类的实例,然后通过提供一个全局唯一获取该类实例的方法帮助用户获取类的实例,用户只需也只能通过调用该方法获取类的实例。

单例模式的设计保证了一个类在整个系统中同一时刻只有一个实例存在,主要被用于一个全局类的对象在多个地方被使用并且对象的状态是全局变化的场景下。同时,单例模式为系统资源的优化提供了很好的思路,频繁创建和销毁对象都会增加系统的资源消耗,而单例模式保障了整个系统只有一个对象能被使用,很好地节约了资源。

单例模式的实现:每次在获取对象前都先判断系统是否已经有这个单例对象,有则返回,没有则创建。需要注意的是,单例模型的类构造函数是私有的,只能由自身创建和销毁对象,不允许除了该类的其他程序使用new关键字创建对象及破坏单例模式。

单例模式的常见写法:懒汉模式(线程安全)、饿汉模式、静态内部类、双重校验锁。

1.懒汉模式(线程安全)

定义一个私有的静态对象instance,之所以定义instance为静态,是因为静态属性或方法是属于类的,能够很好地保障单例对象的唯一性;然后定义一个加锁的静态方法获取该对象,如果该对象为null,则定义一个对象实例并将其赋值给instance,这样下次再获取该对象时便能够直接获取了。因为在获取对象实例时做了加锁操作,所以懒汉模式是线程安全的。

package cn.jaa.singleton_pattern;

/**
 * @author : Jaa
 * @date : 2023-11-28
 * @description:
 */
public class LazySingleton {

    // 私有的静态对象instance
    private static LazySingleton instance;

    // 构造方法
    private LazySingleton() {}

    // 加锁的静态方法获取该对象,加锁则线程安全
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

2.饿汉模式

饿汉模式指在类中直接定义全局的静态对象的实例并初始化,然后提供一个方法获取该实例对象。懒汉模式和饿汉模式的最大不同在于,懒汉模式在类中定义了单例但是并未实例化,实例化的过程是在获取单例对象的方法中实现的,也就是说,在第一次调用懒汉模式时,该对象一定为空,然后去实例化对象并赋值,这样下次就能直接获取对象了;而饿汉模式是在定义单例对象的同时将其实例化的,直接使用便可。也就是说,饿汉模式在类加载完成后该类的实例便已经存在于JVM中了。

package cn.jaa.singleton_pattern;

/**
 * @author : Jaa
 * @date : 2023-11-28
 * @description:
 */
public class HungrySingleton {

    private static HungrySingleton instance = new HungrySingleton();

    public HungrySingleton() {}
    
    public static HungrySingleton getInstance() {
        return instance;
    }
}

3、静态内部类

静态内部类通过在类中定义一个静态内部类,将对象实例的定义和初始化放在内部类中完成,我们在获取对象时要通过静态内部类调用其单例对象。之所以这样设计,是因为类的静态内部类在JVM中是唯一的,这很好地保障了单例对象的唯一性。

package cn.jaa.singleton_pattern;

/**
 * @author : Jaa
 * @date : 2023-11-28
 * @description:
 */
public class Singleton {

    private Singleton() {}

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

4、双重校验锁

双锁模式指在懒汉模式的基础上做进一步优化,给静态对象的定义加上volatile锁来保障初始化时对象的唯一性,在获取对象时通过synchronized (Singleton.class)给单例类加锁来保障操作的唯一性。

package cn.jaa.singleton_pattern;

/**
 * @author : Jaa
 * @date : 2023-11-28
 * @description:
 */
public class Lock2Singleton {

    // 对象锁
    private volatile static Lock2Singleton instance;

    private Lock2Singleton() {}

    public static Lock2Singleton getInstance() {
        if (instance == null) {
            // synchronized方法锁
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Lock2Singleton();
                }
            }
        }
        return instance;
    }
}

你可能感兴趣的:(23种设计模式,单例模式,设计模式)