单例模式

定义: 保证一个类仅有一个实例,并提供一个访问它的全局访问点。

为什么要用单例模式:在我们的系统中,有一些对象其实我们只需要一个,比如说:线程池、缓存、对话框、注册表、日志对象、充当打印机、显卡等设备驱动程序的对象。事实上,这一类对象只能有一个实例,如果制造出多个实例就可能会导致一些问题的产生,比如:程序的行为异常、资源使用过量、或者不一致性的结果。

使用单例模式可以带来下面几个好处:对于频繁使用的对象,可以省略创建对象所花费的时间,这对于那些重量级对象而言,是非常可观的一笔系统开销;由于 new 操作的次数减少,因而对系统内存的使用频率也会降低,这将减轻 GC 压力,缩短 GC 停顿时间。

实现:饿汉式 、懒汉单例模式(线程安全的实现)、懒汉单例模式(双重检查加锁版本)

/**
 * 饿汉式单例模式
 * JVM在加载这个类时就马上创建此唯一的单例实例,
 * 不管你用不用,先创建了再说,如果一直没有被使用,便浪费了空间,典型的空间换时间,每次调用的时候,就不需要再判断,节省了运行时间。
 *
 * @Author: chenqi
 * @Date: 2019.9.25 10:21
 */
public class Sigle {

    private static Sigle sigle = new Sigle();

    private Sigle() {
    }

    public static Sigle getSigle() {
        return sigle;
    }
}
/**
 * 懒汉单例模式(线程安全的实现)
 * 单例实例在第一次被使用时构建,而不是在JVM在加载这个类时就马上创建此唯一的单例实例。
 *
 * @Author: chenqi
 * @Date: 2019.9.25 10:21
 */
public class Sigle2 {

    private static Sigle2 sigle;

    private Sigle2() {
    }

    public synchronized static Sigle2 getSigle() {
        if (sigle == null) {
            sigle = new Sigle2();
        }
        return sigle;
    }
}
/**
 * 懒汉单例模式(双重检查加锁版本)
 * 利用双重检查加锁(double-checked locking),首先检查是否实例已经创建,
 * 如果尚未创建,“才”进行同步。这样以来,只有一次同步,这正是我们想要的效果。
 *
 * @Author: chenqi
 * @Date: 2019.9.25 10:21
 */
public class Sigle3 {

    //volatile保证,当sigle变量被初始化成Sigle3实例时,多个线程可以正确处理sigle变量
    private volatile static Sigle3 sigle;

    private Sigle3() {
    }

    public static Sigle3 getSigle() {
        if (sigle == null) {
            synchronized (Sigle.class) {
                if (sigle == null) {
                    sigle = new Sigle3();
                }
            }
        }
        return sigle;
    }
}

1

Last modification:October 24th, 2019 at 01:57 pm