單例模式的優缺點

單例模式的優缺點緩存

一、時間和空間安全

比較上面兩種寫法:懶漢式是典型的時間換空間,也就是每次獲取實例都會進行判斷,看是否須要建立實例,浪費判斷的時間。固然,若是一直沒有人使用的話,那就不會建立實例,則節約內存空間。併發

餓漢式是典型的空間換時間,當類裝載的時候就會建立類實例,無論你用不用,先建立出來,而後每次調用的時候,就不須要再判斷了,節省了運行時間。性能

二、線程安全spa

(1)從線程安全性上講,不加同步的懶漢式是線程不安全的,好比,有兩個線程,一個是線程A,一個是線程B,它們同時調用getInstance方法,那就可能致使併發問題。以下示例:線程

    public static  Singleton getInstance(){  
        if(instance == null){  
     
     
     
            instance = new Singleton();  
        }  
        return instance;  
    } 

程序繼續運行,兩個線程都向前走了一步,以下:code

    public static  Singleton getInstance(){  
        if(instance == null){  
     
     
     
     
     
     
     
     
     
            instance = new Singleton();  
        }  
        return instance;  
    } 

(2)餓漢式是線程安全的,由於虛擬機保證只會裝載一次,在裝載類的時候是不會發生併發的。xml

(3)如何實現懶漢式的線程安全呢?blog

固然懶漢式也是能夠實現線程安全的,只要加上synchronized便可,以下:內存

  1. public static synchronized Singleton getInstance(){} 

可是這樣一來,會下降整個訪問的速度,並且每次都要判斷。那麼有沒有更好的方式來實現呢?

(4)雙重檢查加鎖

可使用"雙重檢查加鎖"的方式來實現,就能夠既實現線程安全,又可以使性能不受到很大的影響。那麼什麼是"雙重檢查加鎖"機制呢?

所謂雙重檢查加鎖機制,指的是:並非每次進入getInstance方法都須要同步,而是先不一樣步,進入方法事後,先檢查實例是否存在,若是不存 在才進入下面的同步塊,這是第一重檢查。進入同步塊事後,再次檢查實例是否存在,若是不存在,就在同步的狀況下建立一個實例,這是第二重檢查。這樣一來, 就只須要同步一次了,從而減小了屢次在同步狀況下進行判斷所浪費的時間。

雙重檢查加鎖機制的實現會使用一個關鍵字volatile,它的意思是:被volatile修飾的變量的值,將不會被本地線程緩存,全部對該變量的讀寫都是直接操做共享內存,從而確保多個線程能正確的處理該變量。

看看代碼可能會更加清楚些。示例代碼以下:

    public class Singleton {  
        /**  
         * 對保存實例的變量添加volatile的修飾  
         */  
        private volatile static Singleton instance = null;  
        private Singleton(){  
        }  
        public static  Singleton getInstance(){  
            //先檢查實例是否存在,若是不存在才進入下面的同步塊  
            if(instance == null){  
                //同步塊,線程安全地建立實例  
                synchronized(Singleton.class){  
                    //再次檢查實例是否存在,若是不存在才真正地建立實例  
                    if(instance == null){  
                        instance = new Singleton();  
                    }  
                }  
            }  
            return instance;  
        }  
    } 

 

這種實現方式能夠實現既線程安全地建立實例,而又不會對性能形成太大的影響。它只是在第一次建立實例的時候同步,之後就不須要同步了,從而加快了運行速度。

相關文章
相關標籤/搜索