單例模式懶漢式代碼如下為什么我的輸出語句都是“My...

來源:百度知道    2020/2/15 20:33:51
責任編輯:張小俊
字體:

一、基本的實現思路:單例的實現主要是通過以下兩個步驟:1、將該類的構造方法定義為私有方法,這樣其

好心游戲問答中心有網友提出了一個比較有代表性的問題【單例模式懶漢式代碼如下為什么我的輸出語句都是“My...】,小編覺得可能對其他網友也有幫助,所以將此問答整理出來了,希望對您有幫助。

小編為您搜羅的答案1

單例模式的話,為什么要用反射呢?JDK1.7以上的話,使用雙檢驗模式才能實現真正意義上的單例模式

直接輸出對象,就調用了它的默認 toString() 方法了

餓漢式: public class Singleton{

你可以在 MySingle 里重載一下這個方法,改變輸出的東西 請注意:本文為編輯制作專題提供的資訊,頁面顯示的時間僅為生成靜態頁面時間而非具體內容事件發生的時間,由此給您帶來的不便敬請諒解!

1、餓漢式是線程安全的,在類創建的同時就已經創建好一個靜態的對象供系統使用,以后不在改變。懶漢式如果

擴展閱讀,根據您訪問的內容系統為您準備了以下內容,希望對您有幫助。

單例模式懶漢式代碼如下為什么我的輸出語句都是“[email protected]“@c17164這是什么意思?

直接輸出對象,就調用了它的默認 toString() 方法了

你可以在 MySingle 里重載一下這個方法,改變輸出的東西

java中的單例模式的代碼怎么寫

我從我的博客里把我的文章粘貼過來吧,對于單例模式模式應該有比較清楚的解釋:

單例模式在我們日常的項目中十分常見,當我們在項目中需要一個這樣的一個對象,這個對象在內存中只能有一個實例,這時我們就需要用到單例。

一般說來,單例模式通常有以下幾種:

1.饑漢式單例

public class Singleton {

private Singleton(){};

private static Singleton instance = new Singleton();

public static Singleton getInstance(){

return instance;

}

}

這是最簡單的單例,這種單例最常見,也很可靠!它有個唯一的缺點就是無法完成延遲加載——即當系統還沒有用到此單例時,單例就會被加載到內存中。

在這里我們可以做個這樣的測試:

將上述代碼修改為:

public class Singleton {

private Singleton(){

System.out.println("createSingleton");

};

private static Singleton instance = new Singleton();

public static Singleton getInstance(){

return instance;

}

public static void testSingleton(){

System.out.println("CreateString");

}

}

而我們在另外一個測試類中對它進行測試(本例所有測試都通過Junit進行測試)

public class TestSingleton {

@Test

public void test(){

Singleton.testSingleton();

}

}

輸出結果:

createSingleton

CreateString

我們可以注意到,在這個單例中,即使我們沒有使用單例類,它還是被創建出來了,這當然是我們所不愿意看到的,所以也就有了以下一種單例。

2.懶漢式單例

public class Singleton1 {

private Singleton1(){

System.out.println("createSingleton");

}

private static Singleton1 instance = null;

public static synchronized Singleton1 getInstance(){

return instance==null?new Singleton1():instance;

}

public static void testSingleton(){

System.out.println("CreateString");

}

}

上面的單例獲取實例時,是需要加上同步的,如果不加上同步,在多線程的環境中,當線程1完成新建單例操作,而在完成賦值操作之前,線程2就可能判

斷instance為空,此時,線程2也將啟動新建單例的操作,那么多個就出現了多個實例被新建,也就違反了我們使用單例模式的初衷了。

我們在這里也通過一個測試類,對它進行測試,最后面輸出是

CreateString

可以看出,在未使用到單例類時,單例類并不會加載到內存中,只有我們需要使用到他的時候,才會進行實例化。

這種單例解決了單例的延遲加載,但是由于引入了同步的關鍵字,因此在多線程的環境下,所需的消耗的時間要遠遠大于第一種單例。我們可以通過一段測試代碼來說明這個問題。

public class TestSingleton {

@Test

public void test(){

long beginTime1 = System.currentTimeMillis();

for(int i=0;i<100000;i++){

Singleton.getInstance();

}

System.out.println("單例1花費時間:"+(System.currentTimeMillis()-beginTime1));

long beginTime2 = System.currentTimeMillis();

for(int i=0;i<100000;i++){

Singleton1.getInstance();

}

System.out.println("單例2花費時間:"+(System.currentTimeMillis()-beginTime2));

}

}

最后輸出的是:

單例1花費時間:0

單例2花費時間:10

可以看到,使用第一種單例耗時0ms,第二種單例耗時10ms,性能上存在明顯的差異。為了使用延遲加載的功能,而導致單例的性能上存在明顯差異,

是不是會得不償失呢?是否可以找到一種更好的解決的辦法呢?既可以解決延遲加載,又不至于性能損耗過多,所以,也就有了第三種單例:

3.內部類托管單例

public class Singleton2 {

private Singleton2(){}

private static class SingletonHolder{

private static Singleton2 instance=new Singleton2();

}

private static Singleton2 getInstance(){

return SingletonHolder.instance;

}

}

在這個單例中,我們通過靜態內部類來托管單例,當這個單例被加載時,不會初始化單例類,只有當getInstance方法被調用的時候,才會去加載

SingletonHolder,從而才會去初始化instance。并且,單例的加載是在內部類的加載的時候完成的,所以天生對線程友好,而且也不需要

synchnoized關鍵字,可以說是兼具了以上的兩個優點。

4.總結

一般來說,上述的單例已經基本可以保證在一個系統中只會存在一個實例了,但是,仍然可能會有其他的情況,導致系統生成多個單例,請看以下情況:

public class Singleton3 implements Serializable{

private Singleton3(){}

private static class SingletonHolder{

private static Singleton3 instance = new Singleton3();

}

public static Singleton3 getInstance(){

return SingletonHolder.instance;

}

}

通過一段代碼來測試:

@Test

public void test() throws Exception{

Singleton3 s1 = null;

Singleton3 s2 = Singleton3.getInstance();

//1.將實例串行話到文件

FileOutputStream fos = new FileOutputStream("singleton.txt");

ObjectOutputStream oos =new ObjectOutputStream(fos);

oos.writeObject(s2);

oos.flush();

oos.close();

//2.從文件中讀取出單例

FileInputStream fis = new FileInputStream("singleton.txt");

ObjectInputStream ois = new ObjectInputStream(fis);

s1 = (Singleton3) ois.readObject();

if(s1==s2){

System.out.println("同一個實例");

}else{

System.out.println("不是同一個實例");

}

}

輸出:

不是同一個實例

可以看到當我們把單例反序列化后,生成了多個不同的單例類,此時,我們必須在原來的代碼中加入readResolve()函數,來阻止它生成新的單例

public class Singleton3 implements Serializable{

private Singleton3(){}

private static class SingletonHolder{

private static Singleton3 instance = new Singleton3();

}

public static Singleton3 getInstance(){

return SingletonHolder.instance;

}

//阻止生成新的實例

public Object readResolve(){

return SingletonHolder.instance;

}

}

再次測試時,就可以發現他們生成的是同一個實例了。

如何寫一個簡單的單例模式?

一、基本的實現思路:

單例的實現主要是通過以下兩個步驟:

1、將該類的構造方法定義為私有方法,這樣其他處的代碼就無法通過調用該類的構造方法來實例化該類的對象,只有通過該類提供的靜態方法來得到該類的唯一實例;

2、在該類內提供一個靜態方法,當我們調用這個方法時,如果類持有的引用不為空就返回這個引用,如果類保持的引用為空就創建該類的實例并將實例的引用賦予該類保持的引用。

二、示范如下:

1、枚舉實現單例:

2、懶漢式線程不安全:

3、懶漢式線程安全:

4、餓漢式:

5、雙重校驗鎖:

6、靜態內部類:

擴展資料:

一、單列模式簡介:

單例模式是設計模式中最簡單的形式之一。這一模式的目的是使得類的一個對象成為系統中的唯一實例。要實現這一點,可以從客戶端對其進行實例化開始。因此需要用一種只允許生成對象類的唯一實例的機制,“阻止”所有想要生成對象的訪問。使用工廠方法來*實例化過程。這個方法應該是靜態方法(類方法),因為讓類的實例去生成另一個唯一實例毫無意義。

二、懶漢與餓漢:

1、懶漢方式:指全局的單例實例在第一次被使用時構建。

2、餓漢方式:指全局的單例實例在類裝載時構建。

三、單例模式的三要點:

1、某個類只能有一個實例。

2、它必須自行創建這個實例。

3、它必須自行向整個系統提供這個實例。

四、優缺點:

1、優點:

①實例控制:單例模式會阻止其他對象實例化其自己的單例對象的副本,從而確保所有對象都訪問唯一實例。

②靈活性:因為類控制了實例化過程,所以類可以靈活更改實例化過程。

2、缺點:

①開銷:雖然數量很少,但如果每次對象請求引用時都要檢查是否存在類的實例,將仍然需要一些開銷?梢酝ㄟ^使用靜態初始化解決此問題。

②可能的開發混淆:使用單例對象(尤其在類庫中定義的對象)時,開發人員必須記住自己不能使用new關鍵字實例化對象。因為可能無法訪問庫源代碼,因此應用程序開發人員可能會意外發現自己無法直接實例化此類。

③對象生存期:不能解決刪除單個對象的問題。在提供內存管理的語言中(例如基于.NET Framework的語言),只有單例類能夠導致實例被取消分配,因為它包含對該實例的私有引用。在某些語言中(如 C++),其他類可以刪除對象實例,但這樣會導致單例類中出現懸浮引用。

參考資料:百度百科單列模式

為您準備的好內容:

www.ykbrdx.live true http://getqq.haoxyx.com/g/3528/35281660.html report 9255 好心游戲問答中心有網友提出了一個比較有代表性的問題【單例模式懶漢式代碼如下為什么我的輸出語句都是“My...】,小編覺得可能對其他網友也有幫助,所以將此問答整理出來了,希望對您有幫助。小編為您搜羅的答案1直接輸出對象,就調用了它的默認toString()方法了你可以在MySingle里重載一下這個方法,改變輸出的東西請注意:本文為編輯制作專題提供的資訊,頁面顯示的時間僅為生成靜態頁面時間而非具體內容事件發生的時間,由此給您帶來的不便敬請諒解!
最近關注
首頁推薦
熱門圖片
最新添加資訊
24小時熱門資訊
精彩資訊
精彩推薦
熱點推薦
真視界
精彩圖片
社區精粹
關于本站 | 廣告服務 | 手機版 | 商務合作 | 免責申明 | 招聘信息 | 聯系我們
Copyright © 2004-2017 haoxyx.com All Rights Reserved. 好心游戲網 版權所有
京ICP備10044368號-1 京公網安備11010802011102號
公式规律区杀四肖