Java -- 單例設計模式

Java中單例(Singleton)模式是一種廣泛使用的設計模式。單例模式的主要作用是保證在Java程序中,某個類只有一個實例存在。一些管理器和控制器常被設計成單例模式。

1,餓漢式---在類初始化時,已經自行實例化

public class Person{
     private static final Person person=new Person();
     //私有構造函數,外界無法使用
    private Person(){
    }

    //提供一個方法,獲得對象
    public static Person getPerson(){
         return person;
    }
}

注:餓漢式在類創建的同時就已經創建好一個靜態的對象供系統使用,以后不再改變,所以天生是線程安全的。

缺點:餓漢式在類創建的同時就實例化一個靜態對象出來,不管之后會不會使用這個單例,都會占據一定的內存,但是相應的,在第一次調用時速度也會更快,因為其資源已經初始化完成,

2,懶漢式(線程不安全)--顧名思義,什么時候用,什么時候創建

public class Person{
    private static Person person;
    //私有構造函數
    private Person(){
    }
    public static Person getPerson(){
        if(person==null){
            person=new Person();
        }
        return person;
    }

3,懶漢式(線程安全)

public class Person{
      private static Person person=null;
      
      private Person(){
      }
      //添加 synchronized 同步鎖
      public static synchronized Person getPerson(){
      if(person==null){
          person=new Person();
      }
      return person;
      }
}

注:在2.懶漢式基礎上,添加同步鎖,使得在多線程中可以使用。例如:當兩個線程同時想創建實例,由于同一時刻只有一個線程能夠得到同步鎖,當第一個線程得到后第二個線程只能等待,如果沒有創建該實例,就會創建。第一個線程釋放同步鎖以后第二個線程才能加上同步鎖,執行內部代碼,由于第一個線程已經創建了實例,所以第二個線程不需要重復創建。保證了多線程環境下也只有一個實例。

缺點:每次通過 getPerson() 方法得到實例的時候都會有一個試圖去獲取同步鎖的過程,然而加鎖是很耗時的,所以能避免就避免。

4,懶漢式(雙重鎖,線程安全)

public class Person{
      private static Person person=null;
      private Person(){
      }

      public static Person getPerson(){
            if(person==null){
                synchronized(Person.class){
                      if(person==null){
                            person=new Person();
                       }
                 }
            }
            return person;
      }
}

注:只有在person==null的時候,才需要獲取同步鎖,創建一次實例。當實例被創建,則無需試圖加同步鎖,避免3中的問題。

缺點:使用雙重if判斷,復雜,容易出錯。

5,靜態內部類(建議使用)

public class Person{
      private Person(){
      }
      /** 
        * 靜態初始化器,由JVM來保證線程安全 
        */ 
      private static class SingletonPerson{
            private final static Person person=new Person();
      }

      public static Person getPerson(){
            return SingletonPerson.person;
      }
}

注:上面的SingletonPerson內部類的實例與外部類的實例沒有綁定關系,只有被調用才會被加載,也就是實現了延時加載。即按需創建實例。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 1.應用場景: 當需要保證類在內存中的對象唯一性,可以使用單例模式,不想創建多個實例浪費資源,或者避免多個實例由于...
    發光的魚閱讀 269評論 0 0
  • 單例是應用開發中一種設計模式,主要應用場景為:當且僅當系統中只能保留一個對象時使用。本文提出4中可以在生產環境中使...
    瘋狂的冰塊閱讀 394評論 0 3
  • 單例模式(SingletonPattern)一般被認為是最簡單、最易理解的設計模式,也因為它的簡潔易懂,是項目中最...
    成熱了閱讀 4,292評論 4 34
  • 1 場景問題# 1.1 讀取配置文件的內容## 考慮這樣一個應用,讀取配置文件的內容。 很多應用項目,都有與應用相...
    七寸知架構閱讀 6,885評論 12 68
  • 一位超市里偷雞腿的母親成了兒童節期間最熱門的新聞,穿著寒酸,攜著病孩,偷一袋雜糧聊以糊口,一只雞腿和一本兒童讀物是...
    二雙閱讀 252評論 0 0