若是在高并发时候,使用这种单例模式
publci class Singleton{
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
可能会出现多个指向改类的对象,这是什么状况呢?
从上面图能够看到,在一、2状况都没有建立对象,到了3时候Thread1建立一个对象,而Thread2并不知道,因此在4的状况下面Thread2也建立了对象,因此就出现该类不一样对象,若是是使用C++语言实现这种模式,并且没有手工去回收就可能出现内存泄露状况。解决的方法是使用关键字synchronized代码以下:
publci class Singleton{
private static Singleton instance = null;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
这样一来无论多少个线程访问都是实现一个对象实例化了。可是若是使用该关键字可能性能方面有所下降,由于每次访问时候都只能一个线程获取到该对象,当出现多个线程访问时候就会出现排队等待的状况,为了解决这种状况只须要在建立时候使用该关键字就能够了
publci class Singleton{
private static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null)
instance = new Singleton();
}
}
return instance;
}
}
由于第一次使用该对象时候才须要检查该对象是否已经建立了,而第二次检查改对象是否为空是为了不一、2的状况,由于无论是Thread1或者是Thread2拿到线程锁都不会阻止另外的线程建立对象,由于到了2的状况中,若是Thread1已经拿到线程锁以后,建立对象可是到了Thread2获取到线程锁时候,也建立对象因此也会出现不一样对象实例的状况,这种两次检查叫作double click locking模式并发