java單例模式的幾種實現

來源:互聯網
上載者:User

標籤:volatile   使用   ret   消極式載入   懶漢   stat   pre   code   類裝載   

單例模式是用來保證這個類在運行期間只會被建立一個類執行個體,另外,單例模式提供了一個全域唯一訪問這個類執行個體的訪問點,就是getInstance方法。

對於單例模式而言,不管採用何種實現方式,它都只是關心類執行個體的建立問題,不關心具體的業務功能。

第一種方案:懶漢式

懶漢式的類的執行個體建立是在getInstance方法中,懶漢式是典型的時間換空間,也就是每次擷取執行個體都會進行判斷,看是否需要建立執行個體,浪費判斷的時間。當然,如果一直沒人使用的話,那就不會建立執行個體,則節約記憶體空間

package 單例模式;/** * 懶漢式 * @author Administrator * */public class Singleton1 {    private static Singleton1 uniqueInstance = null;        private Singleton1(){}        public static synchronized Singleton1 getInstance(){        if(uniqueInstance == null){            uniqueInstance = new Singleton1();        }        return uniqueInstance;    }    }

這種懶漢式不加同步,所以是線程不安全的,可以加上synchornized使得安全執行緒:

public static synchronized Singleton getInstance(){}

但是這樣會降低整個訪問的速度,而且每次都要判斷,可以使用“雙重檢查加鎖”使得即安全執行緒,又能使效能不受到很大的影響。

“雙重檢查加鎖”是指並不是每次進入getInstance方法都需要同步,而是先不同步,進入方法過後,先檢查執行個體是否存在,如果不存在才進入下面的同步塊,這是第一重檢查,進入同步塊過後,再次檢查執行個體是否存在,不過不存在,就在同步的情況下建立一個執行個體,這是第二重檢查。這樣一來,就只需要同步一次了,從而減少了多次在同步的情況下進行判斷所浪費的時間,實現如下:

package 單例模式;/** * 雙重加鎖懶漢式 * @author Administrator * */public class Singleton3 {        private volatile static Singleton3 instance = null;        private Singleton3(){}        public static Singleton3 getInstance(){        if(instance == null){            synchronized (Singleton3.class) {                if(instance == null){                    instance = new Singleton3();                }            }        }        return instance;    }}

第二種方案:餓漢式

餓漢式是典型的空間換時間,當類載入的時候就會建立類執行個體,不管你用不用,先建立出來,然後每次電泳的時候,就不需要再判斷了,節省了已耗用時間,餓漢式是安全執行緒的

package 單例模式;/** * 餓漢式 * @author Administrator * */public class Singleton2 {        private static Singleton2 uniqueInstance= new Singleton2();        private Singleton2(){}        public static Singleton2 getInstance(){        return uniqueInstance;    }}

Java中一種更好的單例實現方式:


上面兩種方案都有一定的缺陷,那麼有沒有一種方法既能夠實現消極式載入,又能夠實現安全執行緒呢?

要想實現安全執行緒,可以採用靜態初始化器的方式,它可以由JVM來保證線程的安全性,例如前面的餓漢式,但這樣一來,會浪費一定的空間。

如果有一種方法能夠讓類裝載的時候不去初始化對象,不就解決問題了嗎?一種可行的方法就是採用內部類,在這個內部類裡面去建立對象執行個體,這樣一來,只要不實用到這個類級內部類,就不會建立對象執行個體,從而同時實現消極式載入和安全執行緒。

實現如下:

package 單例模式;/** * 使用內部靜態類,安全執行緒且高效 * @author Administrator * */public class Singleton4 {        private static class SingletonHolder{        private static Singleton4 instance = new Singleton4();    }        private Singleton4(){            }    public static Singleton4 getInstance(){        return SingletonHolder.instance;    }}

PS:不久前去參加珍愛網的春招,java開發工程師的面試有道題問到安全執行緒且高效的單例模式,就可以採用內部類的方式實現,可惜當時不懂。

java單例模式的幾種實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.