设计模式之单例模式

什么是设计模式?其实简单的理解就是前人留下来的一些经验总结

一、懒汉式

懒汉式的特点就是在getInstance()方法时候才进行初始化

public class Singleton {
    private static Singleton instance;
    private Singleton() {
    }
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

这种单列模式在线程并发时候就可能会产生多个实例,称为线程不安全

二、懒汉式(线程安全)

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

可以看出加入同步关键字synchronized
这样实现了线程的安全,但是每次调用都会实现同步,导致效果很低

三、双重检测机制

public class Singleton {

    private static Singleton instance;

    private Singleton() {
    }

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

二次检查实例是否创建,第一次检查没有创建,进行同步,同步后第二次检查,这种方法看似很完美,不过也有缺点,在于instance = new Singleton();这条语句,新建对象包含了下面三个步骤:
1、分配内存
2、执行构造方法的初始化
3、将对象指向分配的内存空间

由于java编译器为了尽可能减少内存操作速度远慢于CPU运行速度所带来的CPU空置的影响,虚拟机会按照自己的一些规则将程序编写顺序打乱——即写在后面的代码在时间顺序上可能会先执行,而写在前面的代码会后执行——以尽可能充分地利用CPU就会出现指令重排序(happen-before),从而导致上面的三个步骤执行顺序发生改变。正常情况下是123,但是如果指令重排后执行为1,3,2那么久会导致instance 为空,进而导致程序出现问题。解决方法呢?java中有一个关键字volatile,有一个作用就是防止指令重排。

private static Singleton instance;

饿汉式

饿汉式的特点就是在类加载的时候就进行初始化操作

public class Singleton{
    private static final Singleton instance = new Singleton();

    private Singleton() {
    }

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

与懒汉式相比,它是线程安全的,无需用同步关键字修饰
优点就是由于没有加锁,执行效率比较高
缺点就是在类加载时就初始化,会浪费内存

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