美文网首页
Java单例模式

Java单例模式

作者: LinkedIn | 来源:发表于2017-04-12 22:00 被阅读0次

简单引入

单例设计模式作为最简单,最常用的设计模式。一般是这两中写法,这两种写法教科书所谓的标准写法,但是实际上存在不少问题。后面介绍标准写法,以规避这些问题。

1.懒汉式:

···
/**
* 问题在于,当多线程工作的时候,如果有多个线程同时运行到if (instance ==
* null),都判断为null,那么两个线程就各自会创建一个实例——这样一来,就不是单例了。
*/
class Singleton {

private Singleton() {
};

private static Singleton s;

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

}

···
2.恶汉式
···
class Singleton {
private Singleton() {
}

private static Singleton singleton = new Singleton();

public static Singleton getInstance() {
    return singleton;
}

}
···

标准写法

改变懒汉式1.

(规避线程安全问题)加上 synchronized修饰方法即可
···
class Singleton {

private Singleton() {
};

private static Singleton s;

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

}

···

改变懒汉式2. 双重检查 Double-Check』写法

1.第一个if 只有instance为null的时候,才进入synchronized的代码段——大大减少了几率。
2.第二个if 是为了防止可能出现多个实例的情况。
···
class DoubleCheck {

private DoubleCheck() {
}

private static DoubleCheck dCheck;

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

}

···

改变懒汉式2.之终极版 防止指令重排列 volatile

不知道原子操作,与指令重排的建议复习下
···
class DoubleCheck2 {
private DoubleCheck2() {
}

private static volatile DoubleCheck2 sCheck;

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

}
···

1.恶汉式:

说白了,有classloder装载 就是一开始就创建类

···
/*
* 缺点也就只是饿汉式单例本身的缺点所在了——由于INSTANCE的初始化是在类加载时进行的,而类的加载是由ClassLoader来做的,
* 所以开发者本来对于它初始化的时机就很难去准确把握:
*
* 可能由于初始化的太早,造成资源的浪费 如果初始化本身依赖于一些其他数据,那么也就很难保证其他数据会在它初始化之前准备好。
*/
class Singleton {
private Singleton() {
}

private static final Singleton singleton = new Singleton();

public static Singleton getInstance() {
    return singleton;
}

}

···

由于静态内部类实现

···
class innerSingleton {
private innerSingleton() {

}

private static class SingletonHolder {
    private static final innerSingleton SINGLETON = new innerSingleton();
}

public static innerSingleton getInstance() {
    return SingletonHolder.SINGLETON;
}

}
···

相关文章

网友评论

      本文标题:Java单例模式

      本文链接:https://www.haomeiwen.com/subject/tbkvattx.html