标题: 关于单例设计模式的一些分享 [打印本页] 作者: 徐启坤 时间: 2013-6-23 15:18 标题: 关于单例设计模式的一些分享 对于单例模式的“懒汉式”和“饿汉式”大家都比较熟悉了,先简单说一下
饿汉式就比较简单了,今天的重点是后面的懒汉式:
class Single
{
private static final Single s = new Single();
private Single(){}
public static Single getInstance()
{
return s;
}
}
懒汉式就是延迟加载,但一般的形式会出现线程安全问题,所以出现了以下的改良版:通过加锁保证线程安全,双重判断提高效率
class Single
{
private static Single s = null;
private Single(){}
public static Single getInstance()
{
if(s==null)
{
synchronized(Single.class)
{
if(s==null)
s = new Single();
}
}
return s;
}
}
以上就是我们通常见到的单例模式,但是昨天看到了一篇博客,今天将主要内容跟大家分享一下:
java平台内存模型中有一个叫“无序写”(out-of-order writes)的机制。正是这个机制导致了双重检查加锁方法的失效。这个问题的关键在上面代码中的:s = new Singleton(); 这行其实做了两个事情:1、调用构造方法,创建了一个实例。2、把这个实例赋值给 s 这个实例变量。可问题就是,这两步jvm是不保证顺序的。也就是说。可能在调用构造方法之前,s 已经被设置为非空了。
也就是说如果有一个A线程在调用构造方法之前将 s 变量置为非空了,正好在此时停了下来,线程B过来判断 s 为非空,则将 s 返回了,但返回的却是无效的引用,所以导致错误。
简便的解决方法就是使用内部类的形式:
public class Singleton {
//内部类
private static class SingletonHolder{
//单例变量
private static Singleton instance = new Singleton();
}