【转】高并发状况下的单例模式

若是在高并发时候,使用这种单例模式 
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模式并发

相关文章
相关标签/搜索