Java設計模式の單例模式

來源:互聯網
上載者:User

標籤:--   ==   反射   html   資料   for   ilo   避免   target   

--------------------------------------------------

目錄

  1.定義

  2.常見的集中單例實現

    a.餓漢式,安全執行緒 但效率比較低

    b.單例模式的實現:飽漢式,非安全執行緒

    c.飽漢式,安全執行緒簡單實現

    d.安全執行緒 並且效率高  單例模式最優方案

  3.總結

    a.使用枚舉的單例模式

    b.使用枚舉,static處調用,初始化一次

--------------------------------------------------

 

1.定義

確保一個類只有一個執行個體,並提供一個全域訪問點!

2.常見的集中單例實現

  a.餓漢式,安全執行緒 但效率比較低

/**  * 單例模式的實現:餓漢式,安全執行緒 但效率比較低  */  public class SingletonTest {      // 定義一個私人的構造方法    private SingletonTest() {      }      // 將自身的執行個體對象設定為一個屬性,並加上Static和final修飾符    private static final SingletonTest instance = new SingletonTest();      // 靜態方法返回該類的執行個體    public static SingletonTest getInstancei() {          return instance;      }    }

  b.單例模式的實現:飽漢式,非安全執行緒   

/**   * 單例模式的實現:飽漢式,非安全執行緒    *    */  public class SingletonTest {    // 定義私人構造方法(防止通過 new SingletonTest()去執行個體化)    private SingletonTest() {       }       // 定義一個SingletonTest類型的變數(不初始化,注意這裡沒有使用final關鍵字)    private static SingletonTest instance;       // 定義一個靜態方法(調用時再初始化SingletonTest,但是多線程訪問時,可能造成重複初始化問題)    public static SingletonTest getInstance() {           if (instance == null)               instance = new SingletonTest();           return instance;       }   } 

  c.飽漢式,安全執行緒簡單實現  

/**   * 單例模式的實現:飽漢式,安全執行緒簡單實現    *    */  public class SingletonTest {    // 定義私人構造方法(防止通過 new SingletonTest()去執行個體化)    private SingletonTest() {       }       // 定義一個SingletonTest類型的變數(不初始化,注意這裡沒有使用final關鍵字)    private static SingletonTest instance;       // 定義一個靜態方法(調用時再初始化SingletonTest,使用synchronized 避免多線程訪問時,可能造成重的複初始化問題)    public static synchronized  SingletonTest getInstance() {           if (instance == null)               instance = new SingletonTest();           return instance;       }   } 

  d.安全執行緒 並且效率高  單例模式最優方案

/**   * 單例模式最優方案 * 安全執行緒  並且效率高   *   */  public class SingletonTest {     // 定義一個私人構造方法    private SingletonTest() {          }       //定義一個靜態私人變數(不初始化,不使用final關鍵字,使用volatile保證了多線程訪問時instance變數的可見度,避免了instance初始化時其他變數屬性還沒賦值完時,被另外線程調用)    private static volatile SingletonTest instance;      //定義一個共有的靜態方法,返回該類型執行個體    public static SingletonTest getIstance() {         // 對象執行個體化時與否判斷(不使用同步代碼塊,instance不等於null時,直接返回對象,提高運行效率)        if (instance == null) {            //同步代碼塊(對象未初始化時,使用同步代碼塊,保證多線程訪問時對象在第一次建立後,不再重複被建立)            synchronized (SingletonTest.class) {                //未初始化,則初始instance變數                if (instance == null) {                    instance = new SingletonTest();                   }               }           }           return instance;       }   }

 

3.總結

  

  【以上單例模式】傳統的兩私人一公開(私人構造方法、私人靜態執行個體(懶執行個體化/直接執行個體化)、公開的靜態擷取方法)涉及安全執行緒問題(即使有多重檢查鎖也可以通過反射破壞單例)

目前最為安全的實現單例的方法是通過內部靜態enum的方法來實現,因為JVM會保證enum不能被反射並且構造器方法只執行一次。如下

  a.使用枚舉的單例模式

 

/** * 使用枚舉的單例模式 * * @author yzl * @see [相關類/方法](可選) * @since [產品/模組版本] (可選) */public class EnumSingleton{    private EnumSingleton(){}    public static EnumSingleton getInstance(){        return Singleton.INSTANCE.getInstance();    }        private static enum Singleton{        INSTANCE;                private EnumSingleton singleton;        //JVM會保證此方法絕對只調用一次        private Singleton(){            singleton = new EnumSingleton();        }        public EnumSingleton getInstance(){            return singleton;        }    }}

  b.使用枚舉,static處調用,初始化一次

import java.util.ArrayList;import java.util.List;/** * 初始化的優雅實現 * 可以在static處調用, * 也可以在普通方法裡調用,都保證只初始化一次 *  * 當然將enum塊的代碼直接放到StaticInitTest類的private static 方法裡做也是可以的 * * @author yzl * @see [相關類/方法](可選) * @since [產品/模組版本] (可選) */public class StaticInitTest {    private static List<Integer> dataList = null;        static{        dataList = Singleton.INSTANCE.init();    }        /**     *      * 單例模式來填充資料     *     * @author yzl     * @see [相關類/方法](可選)     * @since [產品/模組版本] (可選)     */    private static enum Singleton {        INSTANCE;        private List<Integer> list;                private Singleton(){            fillData();        }        /**         *          * 初始化資料         *         * @see [相關類/方法](可選)         * @since [產品/模組版本](可選)         */        private void fillData(){            list = new ArrayList<Integer>(5);            for(int i =1; i<6; i++){                list.add(i);            }        }        /**         *          * 初始化的入口         *         * @see [相關類/方法](可選)         * @since [產品/模組版本](可選)         */        public List<Integer> init(){            return list;        }    }}

 

參考資料:java單例之enum實現方式

 

     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.