您的位置:首页 > 编程语言 > Java开发

论线程安全的单例模式

2016-07-19 22:20 393 查看
一 懒汉式

第一种  (非线程安全)

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

第二种( 双重检查 ,性能中等)

private static volatile TestSingleton instance = null;

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

第三种 (静态内部类 , 性能最好,利用了classload的时候只会有一个线程去加载和访问这个对象的原理,避免了多线程的问题)

public class Singleton {
private static class LazyHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}


二 饿汉式

public class Singleton1 {
private Singleton1() {}
private static final Singleton1 single = new Singleton1();
//静态工厂方法
public static Singleton1 getInstance() {
return single;
}
}
饿汉

天生线程安全,所以无需要多做介绍。

最后:注意

在懒汉式的第二种方法里。单列对象被声明为volatile。原因如下:

假设没有关键字volatile的情况下,两个线程A、B,都是第一次调用该单例方法,线程A先执行instance
= new Instance(),该构造方法是一个非原子操作,
编译后生成多条字节码指令,由于JAVA的指令重排序,可能会先执行instance的赋值操作,该操作实际只是在内存中开辟一片存储对象的区域后直接返回内存的引用,
之后instance便不为空了,但是实际的初始化操作却还没有执行,如果就在此时线程B进入,就会看到一个不为空的但是不完整(没有完成初始化)的Instance对象,
所以需要加入volatile关键字,禁止指令重排序优化,从而安全的实现单例。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息