单态设计模式是使用很广泛的一个设计模式,这个设计模式的主要目的是通过一定的技术手段来保证在整个软件系统中只存在某个类的一个实例对象。本文会通过一个Singleton(借鉴别人的)的例子来说明单态设计模式。
Singleton的最初版本
这里直接给出Singleton的代码,我们就叫这个版本为1.0版。
//version 1.0
public class Singleton {
private static final Singleton singleton = null;
private Singleton() { }
public static Singleton getInstance() {
if(singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
对上面这个类做个简要的说明:
1.构造函数是private,这主要是防止在这个类的外部产生该类的实例对象。
2.通过一个static的方法getInstance,取得其唯一的实例对象。
Singleton的实际版本
或许你认为这样的代码就达到我们的目的了,其实上面的程序存在着严重的问题,在多线程的情况下,如果有多个线程同时调用getInstance方法,那么可能就会有多个线程同时通过(singleton == null)的检查,于是,多个实例对象被创建出来了,并且有可能造成内存泄露等问题。所以,我们需要通过线程间的同步来解决上面的问题,修改程序代码,升级为1.1版。
//version 1.1
public class Singleton {
private static final Singleton singleton = null;
private Singleton() { }
public static Singleton getInstance() {
if(singleton == null) {
synchronized(Singleton.class) { //静态方法的同步锁为当前类的字节码
singleton = new Singleton();
}
}
return singleton;
}
}
虽然上面的程序中通过synchronized实现了线程间的同步,但是还是存在问题,前面说过的,有可能多个线程同时通过(singleton == null)的条件检查(因为它们并行执行),这样synchronized方法就将多个并行执行的线程编程了串行执行的线程,
一个一个去new,从而得到多个Singleton类的实例对象!看来,我们还得把if(singleton == null)也同步了,升级代码得1.2版。
//version 1.2
public class Singleton {
private static final Singleton singleton = null;
private Singleton() { }
public static Singleton getInstance() {
synchronized(Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
}
return singleton;
}
}
至此,我们已经解决了多个线程间的同步问题,保证了在整个的软件系统中只有一个Singleton的实例对象。然而,还是有一点小问题,我们本来只想同步new这个操作,然而现在进入getInstance的每个线程都同步了。在单态设计模式中只要求创建一个对象,其余的操作都是读取那个对象,不需要同步。所以上面1.2版中的代码就会影响程序性能,因此,我们还得改,在线程同步之前加上if(singleton == null),如果对象已经创建,就不需要在同步线程了,升级程序得到1.3版。
//version 1.3
public class Singleton {
private static final Singleton singleton = null;
private Singleton() { }
public static Singleton getInstance() {
if(singleton == null) {
synchronized(Singleton.class) {
if(singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
到此,我们已经写出了一个很不错的单态设计模式的例子。希望对大家有所帮助。