中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

單例模式之怎么實現我的機器人女友

發布時間:2021-10-25 15:58:14 來源:億速云 閱讀:319 作者:iii 欄目:編程語言

本篇內容介紹了“單例模式之怎么實現我的機器人女友”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

程序代碼如下:


   
   
  
public class GirlFriend {

   private String name;

   public GirlFriend(String name) {
       this.name = name;
       System.out.println("機器人女友制作完成");
   }

   public void smile() {
       System.out.println("笑一個 :-)");
   }

   public void housework() {
       System.out.println("去干家務");
   }

   public void buKeMiaoShu() {
       System.out.println(".......");
   }
}
     
操作也很簡單,直接創建對象就行了。

   
   
  
public static void main(String[] args) {
    GirlFriend girlFriend = new GirlFriend("小麗");
    girlFriend.smile();
    girlFriend.housework();
    girlFriend.buKeMiaoShu();
}
     
你看,馬上就能干活了。

   
   
  
機器人女友制作完成
笑一個 :-)
去干家務
.......
     
小帥很快發現了一個漏洞,如果材料足夠,他能創造無數個對象。
很快,小帥就在黑市上購買了一套材料,回家啟動機器,果然制造出了第二個機器人女友。
小帥難掩心中的興奮,盤算著,再去黑市買幾套材料回來,不就能打印很多個“女友”了?

單例模式


創新基因公司的監控系統很快就發現了這個問題,工程師們加班加點在線升級了系統。
他們采用了一種叫做單例模式的設計模式來保證一臺機器只能生成一個對象。

單例模式之怎么實現我的機器人女友


 更新后的代碼如下:

   
   
  
public class GirlFriend {

   private static GirlFriend girlFriend;

   private String name;

   private GirlFriend(String name) {
       this.name = name;
       System.out.println("機器人女友制作完成");
   }

   /**
    * 對象通過getInstance方法獲取
    * @param name
    * @return
    */
   public static GirlFriend getInstance(String name) {
       if(girlFriend == null) {
           girlFriend = new GirlFriend(name);
       }
       return girlFriend;
   }

   public void smile() {
       System.out.println("笑一個 :-)");
   }

   public void housework() {
       System.out.println("去干家務");
   }

   public void buKeMiaoShu() {
       System.out.println(".......");
   }
}
     

   
   
  
public static void main(String[] args) {
   GirlFriend girlFriend = GirlFriend.getInstance("小麗");
   girlFriend.smile();
   girlFriend.housework();
   girlFriend.buKeMiaoShu();
}
     
創新基因公司的工程師們很滿意,他們開了一個盛大的party,慶祝工作的圓滿完成。
小帥花了重金,在黑市上買了好幾套材料,打算回家打造一個“后宮團”,想想以后的日子真是美滋滋啊。
小帥打開程序一看傻了眼,運行了好多次,獲取的都是同一個對象,“后宮”夢就此破裂了嗎?
小帥不甘心啊。
經過幾天苦思冥想,小帥終于想到了破解方法,這就是多線程:

   
   
  
public static void main(String[] args){
   for(int i = 0; i < 5; i++) {
       new Thread(new Runnable() {
           @Override
           public void run() {
               GirlFriend girlFriend = GirlFriend.getInstance("小麗");
               System.out.println(girlFriend);
           }
       }).start();
   }
}
     
5個線程同時運行,順利創建了3個不同的對象。

   
   
  
機器人女友制作完成
singleton.singleton.GirlFriend@95458f7
機器人女友制作完成
機器人女友制作完成
singleton.singleton.GirlFriend@d9d8ad0
singleton.singleton.GirlFriend@383a0ba
singleton.singleton.GirlFriend@d9d8ad0
singleton.singleton.GirlFriend@d9d8ad0
     
“嗚。嗚。嗚。”,創新基因公司的報警器又響了起來,工程師們都一臉懵逼,這么完美的單例模式怎么還有破綻呢?
最后還是技術總監親自出馬,給工程師們講解,順便畫了一幅圖:

單例模式之怎么實現我的機器人女友


 線程1和線程2判斷girlFriend的時候如果都為空,就會各自創建一個對象,最后就會返回兩個不同的對象了。

工程師們恍然大悟。
“誰知道如何改進嗎?”技術總監問道。

懶漢式

“這個簡單,在getInstance方法上加個synchronized關鍵字就行了!”程序員老王得意的說。

   
   
  
/**
* 對象通過getInstance方法獲取
 * @param name
 * @return
 */
public synchronized static GirlFriend getInstance(String name) {
    if(girlFriend == null) {
        girlFriend = new GirlFriend(name);
    }
    return girlFriend;
}
     
“這樣確實可以,不過,”技術總監話鋒一轉,“你有沒有考慮過效率問題?”
“synchronized同步方法只有第一次創建對象的時候能用到,也就是說一旦創建了girlFriend對象后就用不到這個同步功能了,但是以后每次調用getInstance方法都會進入同步代碼,嚴重降低了效率。”
技術總監犀利地指出了問題所在。

餓漢式

“還有個辦法,可以用全局變量,在類加載的時候就創建對象,所以,實例的創建過程是線程安全的。”程序員小李也想出了一個辦法。

   
   
  
public class GirlFriend {

   // 在類加載的時候就創建對象,是線程安全的
   private static GirlFriend girlFriend = new GirlFriend("小麗");

   private String name;

   private GirlFriend(String name) {
       this.name = name;
       System.out.println("機器人女友制作完成");
   }

   /**
    * 對象通過getInstance方法獲取
    * @return
    */
   public static GirlFriend getInstance() {
       return girlFriend;
   }

   public void smile() {
       System.out.println("笑一個 :-)");
   }

   public void housework() {
       System.out.println("去干家務");
   }

   public void buKeMiaoShu() {
       System.out.println(".......");
   }
}
     
技術總監說:“這是個辦法,不過,這樣的實現方式有幾個問題需要考慮。”
  • 不支持延遲加載(在真正用到對象的時候,再創建實例),在類加載的時候對象就創建好了,如果對象在整個程序中一次都用不到,提前創建就浪費了。


  • 不能控制對象的數量,我們完全可以聲明多個對象,比如:GirlFriend girlFriend1;GirlFriend girlFriend2;GirlFriend girlFriend3。


  • 我們可能沒有足夠的信息在靜態初始化時,實例化每一個對象,對象的構造方法參數,可能要依賴程序后面的運算結果。


但是,我們要活學活用,如果創建對象比較耗時,等我們用到的時候再創建就會很慢,我們想在程序加載的時候提前創建好,是可以用這種方式的。  
“還有沒有其他方法?”技術總監追問道。

雙重檢測

“還有一種辦法,把同步鎖放到方法里面,雙重檢測。”程序員老王想了好久,終于想出了另一種方法。

   
   
  
public class GirlFriend {

   // volatile關鍵字保證了每個線程看到的girlFriend對象都是最新的
   private volatile static GirlFriend girlFriend;

   private String name;

   private GirlFriend(String name) {
       this.name = name;
       System.out.println("機器人女友制作完成");
   }

   /**
    * 對象通過getInstance方法獲取
    * @param name
    * @return
    */
   public static GirlFriend getInstance(String name) {
       if(girlFriend == null) {
           synchronized (GirlFriend.class) {
               if (girlFriend == null) {
                   girlFriend = new GirlFriend(name);
               }
           }
       }
       return girlFriend;
   }

   public void smile() {
       System.out.println("笑一個 :-)");
   }

   public void housework() {
       System.out.println("去干家務");
   }

   public void buKeMiaoShu() {
       System.out.println(".......");
   }
}
     
“檢查girlFriend對象的時候,如果為null就進入同步代碼,每個線程重新判斷girlFriend對象是否為空,volatile關鍵字保證了每個線程看到的girlFriend對象都是最新的(在高版本的 Java中,這里已經不需要使用volatile了)。”
“如果girlFriend對象已經創建了,以后就不會進入同步代碼了,這樣就保證了效率。”老王解釋道。
“恩,這是個好方法,這樣就解決懶漢式方法的低性能和餓漢式方法的延遲加載問題,我們就采用這個方案升級代碼吧。”技術總監贊許道。

總結

單例模式(Singleton Pattern):單例模式確保一個類僅有一個實例,并提供一個訪問它的全局訪問點。
單例模式的有三個要點:
  • 某個類只能有一個實例

  • 它必須自行創建這個實例

  • 它必須自行向整個系統提供這個實例


單例模式是一種對象創建型模式。
單例模式又名單件模式或單態模式。
單例的實現單例有下面幾種經典的實現方式:
- 懶漢式
懶漢式相對于餓漢式的優勢是支持延遲加載。但是,這種實現方式會導致頻繁加鎖、釋放鎖,以及并發度低等問題,頻繁的調用會產生性能瓶頸。
- 餓漢式
餓漢式的實現方式,在類加載的期間,就已經將靜態實例初始化好了,所以,實例的創建是線程安全的。不過,這樣的實現方式不支持延遲加載實例。
- 雙重檢測
雙重檢測的實現方式是既支持延遲加載、又支持高并發的單例實現方式。只要實例被創建之后,再調用 getInstance() 函數都不會進入到加鎖邏輯中。

“單例模式之怎么實現我的機器人女友”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

镇江市| 缙云县| 澳门| 勐海县| 昌图县| 乃东县| 泌阳县| 广南县| 海阳市| 远安县| 江阴市| 丁青县| 乌海市| 建宁县| 疏附县| 新郑市| 阜宁县| 全南县| 兴和县| 社会| 永寿县| 清苑县| 弋阳县| 屏南县| 西宁市| 砀山县| 三亚市| 弥勒县| 永德县| 绥宁县| 石阡县| 剑川县| 万载县| 海淀区| 枣阳市| 武汉市| 河曲县| 长沙县| 文成县| 布尔津县| 防城港市|