Java单例模式源码 五种单例模式的实现

面试中总会问到设计模式,但是,对于应届生来说,最见到那的也是问得最多的就是单例模式,更有甚者直接在手撕代码的时候写单例模式,下面就让我们来看看单例模式都有哪些实现方式吧。
单例模式第一弹-----懒汉式
懒汉式,这种方式等到需要调用getInstance的时候才去初始化,这样有一个好处就是在一定程度上可以节省内存空间。但是也有一个坏处就是在多线程的环境下式不安全的。代码如下:


/**
 * 懒汉模式,就是等到需要的时候采取初始化
 * 在多线程的情况下是不安全的
 */
public class LazySingleton {
    private static LazySingleton instace = null;

    private LazySingleton() {
    }

    public static LazySingleton getInstace() {
        if (instace == null) {
            instace = new LazySingleton();
        }
        return instace;
    }
}

多线程下测试的结果
Java单例模式源码 五种单例模式的实现_第1张图片
虽然简单,但是我们发现确实是不安全的(实例的地址明显不对)。
单例模式第二弹----双检锁模式
其实双检锁就是懒汉模式的进阶版,你不是不安全嘛,于是我就让你安全呗,代码如下

/**
 * 双检锁来实现单例模式,其实就是安全版本的懒汉式单例
 *
 * 如果不加入volatile可能会出现问题
 * instance = new DoubleCheckSingleton();分为三个步骤
 * 1.在堆内存开辟内存空间。
 * 2.在堆内存中实例化SingleTon里面的各个参数。
 * 3.把对象指向堆内存空间。
 * 由于jvm可能存在优化的现象导致乱序执行,比如导致3比2先执行,那么,其他线程来获取的时候就会出错
 */
public class DoubleCheckSingleton {
    private static volatile DoubleCheckSingleton instance = null;

    private DoubleCheckSingleton(){}

    public static DoubleCheckSingleton getInstance(){
        if(instance==null){
            synchronized (DoubleCheckSingleton.class){
                if(instance == null){
                    instance = new DoubleCheckSingleton();
                }
            }
        }
        return instance;
    }
}

单例模式第三弹----饿汉模式
饿汉模式,听名字就知道了,就是一上来就直接加载了,这样就可以避免线程不安全的问题,但是也是会有一个问题就是内存问题了呗。代码如下

/**
 * 饿汉式单例模式,会在最开始就进行实例化,是线程安全的
 */
public class HangerSingleton {
    private static HangerSingleton instance = new HangerSingleton();

    private HangerSingleton() {
    }

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

单例模式第四弹----静态内部类
既然嫌弃饿汉模式不具有懒加载的功能,那么,静态内部类就完全满足这个功能,不但可以懒加载,还安全。代码如下

/**
 * 外部类第一次加载的时候并不会加载静态内部类,直到调用getInstance的时候才会去实例化instance而且智慧去加载一次
 *
 */
public class StaticInnerSingleton {
    private StaticInnerSingleton() {
    }

    private static class StaticInnerSingletonHoler {
        private static StaticInnerSingleton instance = new StaticInnerSingleton();
    }

    public static StaticInnerSingleton getInstance() {
        return StaticInnerSingletonHoler.instance;
    }
}

单例模式第五弹----枚举类
虽然静态内部类是很好了,但是我又嫌弃代码太长,怎么办呢???那就直接使用枚举类了呗,枚举天然就具备单例的特性,多清爽啊。

public enum EnumSingleton {
    instance;
}

以上。。。。。

你可能感兴趣的:(设计模式)