單例模式的兩種寫法:餓漢式單例和懶漢式單例

一般我們在項目開發中有時候常會遇到數據庫的連接(不使用框架),我們常會在dao類中寫一些通用的方法以供後面使用。一般的做法是哪裏需要操作數據庫的方法哪裏就會創建一個對象,然後再引用對象裏面的操作方法,這樣做的不好的地方就是創建的對象比較多,比較消耗內存,降低程序效率,而我們完全可以只創建一個對象,然後哪裏需要哪裏就直接用,無需重新創建,這就是單例模式。

一、懶漢式單例(線程安全,推薦使用)

懶漢式單例顧名思義,它是驅動型的單例模式。當某個用戶(線程)需要某個對象實例時纔會去創建,而再未被需要之前不會主動去創建。在一些需要自己創建的工具類時,可以將其定義爲一個單例類,因爲在整個項目當中工具類只需要創建一次。

優缺點: 類加載較塊,但獲取對象較慢(需要先創建,僅針對第一次實例化),需要進行線程同步,保證線程安全。
注意: 在這個寫法中用到了兩次if(singleton == null)判斷語句,因爲當一個線程執行完if(singleton == null)還未執行下面的語句時,有另一個線程也執行完if語句,然後再執行下面的,此時會產生多個對象,線程不安全。但是當再加一個判斷語句時,當某一個線程已經創建了該對象時,另一個線程在進行執行第二個if語句時直接返回false,從而不會創建多餘的對象。

public class Singleton {//簡單實現一個單例模型

    private static Singleton singleton ;
    private static Object object=new Object();
    /*私有化構造函數,使得在外部不能創建對象,這是實現單例模式的關鍵*/
    private Singleton(){}
    /*獲取object對象鎖,進行線程同步,在前一個線程未釋放該鎖時,其他線程需等待*/
   public static Singleton geiInstance(){
        if(util==null){
            synchronized (object){
                if(util==null){
                    util=new Singleton();
                }
            }
        }
        return util;
    }

    public static void main(String[] args) {
        Singleton singleton1 = Singleton.geiInstance();
        Singleton singleton2 = Singleton.geiInstance();
        System.out.println(singleton 1==singleton 2);
    }
}
//輸出:true

二、餓漢式單例

餓漢式單例即主動型單例模式,不管用戶用不用得到,它都會提前實例化對象等待用戶調用。

優缺點: 在類加載時就已經實例化,因此類加載較慢,但獲取對象比較快,不存在線程安不安全的問題。

public class Singleton {
    private static Singleton  singleton = new Singleton();
    private Singleton(){}
    public static Singleton getSingleton(){
        return singleton;
    }
    public static void main(String[] args) {
        Singleton util1= Singleton.getSingleton();
        Singleton util2= Singleton.getSingleton();
        System.out.println(util1==util2);
    }
}
//輸出:true
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章