设计模式设计模式——小单例有大秘密小单例有大秘密
单例模式大家并不陌生,也都知道它分为什么懒汉式、饿汉式之类的。但是你对单例模式的理解足够透彻吗?今天我带大家一
起来看看我眼中的单例,可能会跟你的认识有所不同。
下面是一个简单的小实例:
//简单懒汉式
public class Singleton {
//单例实例变量
private static Singleton instance = null;
//私有化的构造方法,保证外部的类不能通过构造器来实例化
private Singleton() {}
//获取单例对象实例
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
System.out.println("我是简单懒汉式单例!");
return instance;
}
}
很容易看出,上面这段代码在多线程的情况下是不安全的,当两个线程进入if (instance == null)时,两个线程都判断instance
为空,接下来就会得到两个实例了。这不是我们想要的单例。
接下来我们用加锁的方式来实现互斥,从而保证单例的实现。
//同步法懒汉式
public class Singleton {
//单例实例变量
private static Singleton instance = null;
//私有化的构造方法,保证外部的类不能通过构造器来实例化
private Singleton() {}
//获取单例对象实例
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
System.out.println("我是同步法懒汉式单例!");
return instance;
}
}
加上synchronized后确实保证了线程安全,但是这样就是最好的方法吗?很显然它不是,因为这样一来每次调用getInstance()
方法是都会被加锁,而我们只需要在第一次调用getInstance()的时候加锁就可以了。这显然影响了我们程序的性能。我们继续
寻找更好的方法。
经过分析发现,只需要保证instance = new Singleton()是线程互斥就可以保证线程安全,所以就有了下面这个版本: