国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

單例模式 分析代碼優化方法

2019-11-26 15:13:43
字體:
來源:轉載
供稿:網友

單例模式是23種設計模式之一,是比較簡單的一種設計模式,它的目的是無論調用多少次,都返回同一個對象,它的特點是構造器私有化。

  它分為兩種結構,一種是懶漢式的,一種是餓漢式的,它們各有優缺點,我們先從餓漢式看起,代碼如下:

public class Single {   private static Single single = new Single();    private Single() {    }    public Single getInstance() {     return single;   }  }

通過上面的程序可以看出來雖然我們加載同一個對象的目的確實達到了,但當程序被加載的時候就會創建single這個對象,當這個類有多個這樣的方法時,我們可能會用不到這個對象中大多數單例,就會造成對內存的浪費。所以就出現了懶漢式的單例模式,代碼如下:

public class Single {   private static Single single = null;    private Single() {    }    public Single getInstance() {     if(single==null){       single = new Single();     }     return single;   }  }

這樣,只有當我們真正調用這個對象時它才會被new出來,但是這樣是存在問題的。

  當上面的第二段代碼在第一次加載的時候有兩個線程對其進行了調用,則會產生兩個不同的對象,所以是線程不安全的,這時候就會想到給這個方法加個鎖,加鎖之后的代碼如下:

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

這樣做確實做到了線程安全,但是當加鎖這個方法里面要執行很多東西,調用這個方法花費的時間會很長,這樣對服務器來說是致命的,因為這個方法如果某個線程一直調用的話,其它的線程是沒有辦法調的,服務器就阻塞了,那么升級后的代碼如下:

public class Single {   priate static Single single = null;    private Single() {    }    public Single getInstance() {     if (single == null) {       synchronized (Single.class) {         single = new Single();       }     }     return single;   } }

仔細觀察以后發現這樣并沒有鎖住,當第一次同時有兩個線程到達getInstance()方法if判斷時,其中有一個肯定是阻塞的,當另外一個執行完以后,阻塞這個線程是不會再判斷是否為空的,還是會創建一個對象的,這樣又有多個對象被產生了,再對其進行升級,得到的代碼如下:

public class Single {   private static Single single = null;    private Single() {    }    public Single getInstance() {     if (single == null) {       synchronized (Single.class) {         if (single == null) {           single = new Single();         }       }     }     return single;   } }

這樣就不會產生上面的問題,而且也只鎖一次,因為第二次再執行這個方法時,會跳過if判斷,直接返回single,不會再被鎖,執行效率也會很高。

  但即使是這樣,也還是有問題的,因為我們不能確定在內存中是先給對象賦值,還是先創建了這個對象,所以第二個程序有可能得到的是初始化一半了的對象,在jdk1.5之后,我們可以用volatile這個關鍵字來避免這種情況,代碼如下:

public class Single {   private static volatile Single single = null;    private Single() {    }    public Single getInstance() {     if (single == null) {       synchronized (Single.class) {         if (single == null) {           single = new Single();         }       }     }     return single;   } }

但是這種情況很少使用,我在這里只是為了學習一下,嘻嘻

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 腾冲县| 乐陵市| 勐海县| 绥棱县| 靖江市| 衢州市| 苏尼特左旗| 泗洪县| 措美县| 故城县| 土默特左旗| 泰兴市| 彝良县| 马公市| 冀州市| 临桂县| 襄樊市| 延庆县| 霍林郭勒市| 武陟县| 汶上县| 沛县| 南投市| 深泽县| 拉萨市| 巧家县| 大邑县| 乌兰察布市| 柳州市| 无棣县| 蓬溪县| 昭苏县| 嵊州市| 宣威市| 竹山县| 松江区| 双柏县| 贵德县| 九江县| 色达县| 绥芬河市|