今天打算来复习一下单例模式。单例模式是设计模式里较为简单的一种模式,也非常常用,广泛应用于各种框架当中。所谓单例模式,就是确保一个类只有一个实例,并提供全局访问点。
单例模式有好几种形式,其中最简单的是饿汉式:
class Singleton{
private static Singleton singleton=new Singleton();
private Singleton(){
}
public static Singleton getInstance(){
return singleton();
}
饿汉式在调用实例前已经创建好了对象,比起下面要讲到的懒汉式省去了判断的时间,但由于每次都会实例化对象,浪费一定的空间,所以适用于确定单例对象大多数时候都会被调用的程序。
与饿汉式相对应的是懒汉式:
class Singleton{
private Singleton singleton=null;
private Singleton(){
}
public static Singleton getInstance(){
if(singleton==null){
singleton=new Singleton();
}
return singleton;
}
}
懒汉式在每次获取对象时先判断是否已经实例化对象,如果没有的话再去创建对象。所以,如果在程序的整个生命周期如果没有试图获取对象的话,该单例对象是不会被创建的,省去了空间,但多了一些判断的时间。
上面提到的懒汉式其实并不完善,但出现两个或以上的线程要调用该单例对象的时候,就有可能会发生问题。下面我们来分析一下:
假设现在我们的程序现在有线程A,B两个线程在运行,一开始对象还没被创建,singleton==null为真,A线程进入if语句块之后,在对象创建之前 ,B线程也通过判断进入if语句块,接下来问题就发生了,两个线程创建了两个对象!为了防止这种现象发生,我们需要进行如下改进:
class Singleton{
private static Singleton singleton=null;
private Singleton(){
}
public static synchronized Singleton getInstance(){
if(singleton==null){
singleton=new Singleton();
}
return singleton;
}
}
这样就避免了多线程问题,但无疑同步会大大地降低了性能。更好的方法是使用“双重检查加锁”:
class Singleton{
private static volatile Singleton singleton=null;
private Singleton(){
}
public static Singleton getInstance(){
if(singleton==null){
synchronized(Singleton.class){
if(singleton==null){
singleton=new Singleton();
}
}
}
return singleton;
}
}
以上就是我学到的单例模式的相关内容,以后还有再更新啦!