單例模式(Singleton)的同步鎖synchronized

單例模式,有「懶漢式」和「餓漢式」兩種。安全

懶漢式多線程

單例類的實例在第一次被引用時候才被初始化。性能

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

餓漢式this

單例類的實例在加載的時候就被初始化。線程

public class Singleton {  
    private static Singleton instance = new Singleton();  
     
    private Singleton() {  
         
    }  
     
    public static Singleton getInstance(){  
        return instance;  
    }  
}

在單線程程序中,上面兩種形式基本能夠知足要求了,可是在多線程環境下,單例類就有可能會失效,這個時候就要對其加鎖了,來確保線程安全。code

對線程加鎖用的synchronized關鍵字,這個關鍵字的用法主要也分爲兩種:對象

一種是加在方法名以前,形如:synchronized methodeName(params){……};blog

二是聲明同步塊,形如:synchronized(this){……};get

下面是對懶漢式單例類加上線程同步的實現:同步

同步方法:

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

這種方式效率比較低,性能不是太好,不過也能夠用,由於是對整個方法加上了線程同步,其實只要在new的時候考慮線程同步就好了,這種方法不推薦使用。

同步代碼塊:

public class Singleton {  
    private static Singleton instance;  
    private final static Object syncLock = new Object();  
     
    private Singleton() {  
         
    }  
     
    public static Singleton getInstance(){  
        if (instance == null) {  
            synchronized (syncLock) {  
                if (instance == null) {  
                    instance = new Singleton();  
                }  
            }  
        }  
         
        return instance;  
    }  
}

synchronized同步塊括號中的鎖定對象是採用的一個無關的Object類實例,而不是採用this,由於getInstance是一個靜態方法,在它內部不能使用未靜態的或者未實例的類對象,所以也能夠用下面的方法來實現:

public class Singleton {  
    private static Singleton instance;  
     
    private Singleton() {  
         
    }  
     
    public static Singleton getInstance(){  
        if (instance == null) {  
            synchronized (Singleton.class) {  
                if (instance == null) {  
                    instance = new Singleton();  
                }  
            }  
        }  
         
        return instance;  
    }  
}
相關文章
相關標籤/搜索