java设计模式——单例模式

1.饿汉式

 线程安全,不管用不用都会创建对象,拿空间换时间。

/**
 * 饿汉式
 */
public class Singleton {
    private static Singleton instance = new Singleton ();

    private Singleton () {}

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

 

2.懒汉式

 进行一次非空判断,可能会出现一个或多个线程同时进入if语句,创建多个对象,线程不安全。

/**
 * 懒汉式
 */
public class Singleton {
    private static Singleton instance;

    private Singleton () {}

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

 

3.懒汉式同步锁版

 虽然线程安全,但是锁范围较大,效率较低。

/**
 * 懒汉线程同步锁版
 */
class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

 

4.懒汉式双重检验锁版

依然存在问题instance = new Singleton()这行在JVM大致做了如下操作:
1.给instance分配内存
2.调用Singleton构造函数初始化成员变量
3.将instance对象指向分配的内存空间,执行完这一步,instance就不为null了
JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的,所以此行不是一个原子操作
在 3 执行完毕、2 未执行之前,被线程二抢占了,这时 instance 已经是非 null 了(但却没有初始化),所以线程二会直接返回 instance,然后使用,最后报错。

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;
    }
}    

 

 5.懒汉式双重检验锁最终版

使用volatile关键字来解决上一版的问题,在这里volatile的作用是禁止JVM的指令重排序优化,而不是利用可见性。

/**
 * 双重检验锁最终版
 */

public class Singleton{
    private volatile static Singleton instance;

    private Singleton() {}

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

 

 6.静态内部类版

  由于JVM特殊机制,线程安全,无效率缺陷,属于懒汉式。

//静态内部类版
public class Singleton { private static class SingletonHolder { private static Singleton INSTANCE = new Singleton (); } private Singleton () {} public static final Singleton getInstance() { return SingletonHolder.INSTANCE; }

 

 7.写法最简单的单例-枚举版

//枚举版 线程安全
public enum EasySingleton{ INSTANCE; }

 

posted @ 2019-03-11 19:47  三秋Yis  阅读(184)  评论(0编辑  收藏  举报