免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開(kāi)通VIP
創(chuàng)建型設(shè)計(jì)模式--單例模式

一、單例模式

1、什么是單例模式

  采取一定的方法,使程序中的某個(gè)類只存在一個(gè)實(shí)例對(duì)象,且該類對(duì)外提供一個(gè)獲取該對(duì)象的方法(一般為靜態(tài)方法)。

2、單例模式分類

(1)餓漢式(2種寫法,線程安全)
  靜態(tài)變量
  靜態(tài)代碼塊

(2)懶漢式(3種寫法)
  線程不安全
  線程安全,同步方法
  線程安全,同步代碼塊(不推薦使用)

(3)雙重檢查(推薦使用)
(4)靜態(tài)內(nèi)部類(推薦使用)
(5)枚舉(推薦使用)

3、餓漢式單例模式(靜態(tài)常量版)

(1)步驟:
  step1:構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)
  step2:在類的內(nèi)部創(chuàng)建實(shí)例對(duì)象。
  step3:向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象。
(2)代碼實(shí)現(xiàn):

package singleton.pattern.demo1;/** * 演示 餓漢式單例模式,靜態(tài)變量版 * */public class Demo {    public static void main(String[] args) {        Singleton singleton1 = Singleton.getSingleTon();        Singleton singleton2 = Singleton.getSingleTon();        System.out.println(singleton1 == singleton2); // 由于獲取的為同一個(gè)對(duì)象,所以輸出為true    }}/** * 餓漢式單例模式,靜態(tài)變量版 */class Singleton {    // 在類的內(nèi)部創(chuàng)建實(shí)例對(duì)象。使用靜態(tài)變量,只被加載一次。    private static Singleton singleton = new Singleton();    /**     * 構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)     */    private Singleton() {    }    /**     * 向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象。     *      * @return 實(shí)例對(duì)象     */    public static Singleton getSingleTon() {        return singleton;    }}

(3)優(yōu)缺點(diǎn):
  優(yōu)點(diǎn):寫法簡(jiǎn)單,在類裝載時(shí)完成了實(shí)例化,避免線程同步問(wèn)題。
  缺點(diǎn):在類裝載前完成實(shí)例化,沒(méi)有實(shí)現(xiàn)懶加載(Lazy Loading),可能造成內(nèi)存的浪費(fèi)(比如從不使用該類時(shí)會(huì)造成內(nèi)存的浪費(fèi))。

(4)UML圖:

 

4、餓漢式單例模式(靜態(tài)代碼塊)

(1)步驟:
  step1:構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)
  step2:在類的內(nèi)部聲明實(shí)例對(duì)象,并在靜態(tài)代碼塊中實(shí)例化對(duì)象。
  step3:向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象。
(2)代碼實(shí)現(xiàn):

package singleton.pattern.demo2;/** * 演示 餓漢式單例模式,靜態(tài)代碼塊版 * */public class Demo {    public static void main(String[] args) {        Singleton singleton1 = Singleton.getSingleTon();        Singleton singleton2 = Singleton.getSingleTon();        System.out.println(singleton1 == singleton2); // 由于獲取的為同一個(gè)對(duì)象,所以輸出為true    }}/** * 餓漢式單例模式,靜態(tài)代碼塊版 */class Singleton {    // 在類的內(nèi)部聲明一個(gè)實(shí)例對(duì)象    private static Singleton singleton;    static {        // 在代碼塊中實(shí)例化一個(gè)對(duì)象,同樣只加載一次        singleton = new Singleton();    }    /**     * 構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)     */    private Singleton() {    }    /**     * 向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象。     *      * @return 實(shí)例對(duì)象     */    public static Singleton getSingleTon() {        return singleton;    }}

(3)優(yōu)缺點(diǎn)同上例 餓漢式單例模式(靜態(tài)常量版)

5、懶漢式單例模式(線程不安全)

(1)步驟:
  step1:構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)
  step2:在類的內(nèi)部聲明實(shí)例對(duì)象。
  step3:向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象,在調(diào)用該方法時(shí),才去創(chuàng)建實(shí)例對(duì)象。
(2)代碼實(shí)現(xiàn):

package singleton.pattern.demo3;/** * 演示 懶漢式單例模式,線程不安全版 * */public class Demo {    public static void main(String[] args) {        Singleton singleton1 = Singleton.getSingleTon();        Singleton singleton2 = Singleton.getSingleTon();        System.out.println(singleton1 == singleton2); // 由于獲取的為同一個(gè)對(duì)象,所以輸出為true    }}/** * 懶漢式單例模式,線程不安全版 */class Singleton {    // 在類的內(nèi)部聲明一個(gè)實(shí)例對(duì)象    private static Singleton singleton;    /**     * 構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)     */    private Singleton() {    }    /**     * 向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象。 當(dāng)調(diào)用該方法時(shí),才去檢查并創(chuàng)建一個(gè)實(shí)例對(duì)象。     *      * @return 實(shí)例對(duì)象     */    public static Singleton getSingleTon() {        if (singleton == null) {            singleton = new Singleton();        }        return singleton;    }}

(3)優(yōu)缺點(diǎn):
  優(yōu)點(diǎn):實(shí)現(xiàn)了懶加載。
  缺點(diǎn):只能在單線程下使用,比如線程A與線程B并發(fā)執(zhí)行到 if (singleton == null), 此時(shí)便會(huì)產(chǎn)生多個(gè)實(shí)例對(duì)象。

6、懶漢式單例模式(線程安全,同步方法)

(1)步驟:
  step1:構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)
  step2:在類的內(nèi)部聲明實(shí)例對(duì)象。
  step3:向外暴露一個(gè)靜態(tài)的公共方法(給靜態(tài)方法加個(gè)synchronized關(guān)鍵字,解決同步問(wèn)題)用于獲取實(shí)例對(duì)象,在調(diào)用該方法時(shí),才去創(chuàng)建實(shí)例對(duì)象。
(2)代碼實(shí)現(xiàn):

package singleton.pattern.demo4;/** * 演示 懶漢式單例模式,線程安全,同步方法版 * */public class Demo {    public static void main(String[] args) {        Singleton singleton1 = Singleton.getSingleTon();        Singleton singleton2 = Singleton.getSingleTon();        System.out.println(singleton1 == singleton2); // 由于獲取的為同一個(gè)對(duì)象,所以輸出為true    }}/** * 懶漢式單例模式,線程安全,同步方法版 */class Singleton {    // 在類的內(nèi)部聲明一個(gè)實(shí)例對(duì)象    private static Singleton singleton;    /**     * 構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)     */    private Singleton() {    }    /**     * 向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象,并給方法加個(gè)synchronized關(guān)鍵字,解決同步的問(wèn)題。     * 當(dāng)調(diào)用該方法時(shí),才去檢查并創(chuàng)建一個(gè)實(shí)例對(duì)象。     *      * @return 實(shí)例對(duì)象     */    public static synchronized Singleton getSingleTon() {        if (singleton == null) {            singleton = new Singleton();        }        return singleton;    }}

(3)優(yōu)缺點(diǎn):
  優(yōu)點(diǎn):實(shí)現(xiàn)了懶加載,解決了線程不安全的問(wèn)題。
  缺點(diǎn):效率太低,每個(gè)線程想獲取實(shí)例對(duì)象時(shí),均會(huì)觸發(fā)同步方法,此時(shí)會(huì)等待前一個(gè)線程調(diào)用結(jié)束后才能使用,使效率低。

 

7、懶漢式單例模式(同步代碼塊方法,線程不一定安全)

(1)步驟:
  step1:構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)
  step2:在類的內(nèi)部聲明實(shí)例對(duì)象。
  step3:向外暴露一個(gè)靜態(tài)的公共方法(在靜態(tài)方法內(nèi)部定義一個(gè)代碼塊,解決同步問(wèn)題)用于獲取實(shí)例對(duì)象,在調(diào)用該方法時(shí),才去創(chuàng)建實(shí)例對(duì)象。
(2)代碼實(shí)現(xiàn):

package singleton.pattern.demo5;/** * 演示 懶漢式單例模式,線程不一定安全,同步代碼塊版 * */public class Demo {    public static void main(String[] args) {        Singleton singleton1 = Singleton.getSingleTon();        Singleton singleton2 = Singleton.getSingleTon();        System.out.println(singleton1 == singleton2); // 由于獲取的為同一個(gè)對(duì)象,所以輸出為true    }}/** * 懶漢式單例模式,線程不一定安全,同步代碼塊版 */class Singleton {    // 在類的內(nèi)部聲明一個(gè)實(shí)例對(duì)象    private static Singleton singleton;    /**     * 構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)     */    private Singleton() {    }    /**     * 向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象,在方法內(nèi)部加個(gè)同步代碼塊。 當(dāng)調(diào)用該方法時(shí),才去檢查并創(chuàng)建一個(gè)實(shí)例對(duì)象。     *      * @return 實(shí)例對(duì)象     */    public static Singleton getSingleTon() {        if (singleton == null) {            synchronized (Singleton.class) {                singleton = new Singleton();            }        }        return singleton;    }}

(3)優(yōu)缺點(diǎn):
  優(yōu)點(diǎn):優(yōu)化了了上例 懶漢式單例模式(線程安全,同步方法) 的效率問(wèn)題。
  缺點(diǎn):能滿足大部分線程安全的情況,但是若線程A與線程B并發(fā)執(zhí)行到 if (singleton == null),此時(shí)同步代碼塊的作用就不存在了, 會(huì)產(chǎn)生多個(gè)實(shí)例對(duì)象。

 

8、雙重檢查(Double Check)

(1)步驟:
  step1:構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)
  step2:在類的內(nèi)部聲明實(shí)例對(duì)象,并使用volatile關(guān)鍵字(保證可見(jiàn)性,且防止因JVM指令重排使代碼執(zhí)行順序不對(duì),從而導(dǎo)致代碼執(zhí)行有誤)。
  step3:向外暴露一個(gè)靜態(tài)的公共方法(在靜態(tài)方法內(nèi)部定義一個(gè)代碼塊,解決同步問(wèn)題)用于獲取實(shí)例對(duì)象,在調(diào)用該方法時(shí),才去創(chuàng)建實(shí)例對(duì)象。在上例 懶漢式單例模式(同步代碼塊方法,線程不一定安全) 的基礎(chǔ)上,給同步代碼塊內(nèi)部加個(gè)檢查處理。
(2)代碼實(shí)現(xiàn):

package singleton.pattern.demo6;/** * 演示 單例模式,雙重檢查版 * */public class Demo {    public static void main(String[] args) {        Singleton singleton1 = Singleton.getSingleTon();        Singleton singleton2 = Singleton.getSingleTon();        System.out.println(singleton1 == singleton2); // 由于獲取的為同一個(gè)對(duì)象,所以輸出為true    }}/** * 單例模式,雙重檢查版 */class Singleton {    // 在類的內(nèi)部聲明一個(gè)實(shí)例對(duì)象    private static volatile Singleton singleton;    /**     * 構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)     */    private Singleton() {    }    /**     * 向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象,在方法內(nèi)部加個(gè)同步代碼塊,在代碼塊內(nèi)部增加一個(gè)檢查處理。 當(dāng)調(diào)用該方法時(shí),才去檢查并創(chuàng)建一個(gè)實(shí)例對(duì)象。     *      * @return 實(shí)例對(duì)象     */    public static Singleton getSingleTon() {        if (singleton == null) {            synchronized (Singleton.class) {                if (singleton == null) {                    singleton = new Singleton();                }            }        }        return singleton;    }}

(3)優(yōu)缺點(diǎn):
  優(yōu)點(diǎn):線程安全,延遲加載,效率高。常用于多線程開(kāi)發(fā)。

 

9、靜態(tài)內(nèi)部類

(1)步驟:
  step1:構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)
  step2:在類的內(nèi)部定義一個(gè)靜態(tài)內(nèi)部類(只有被調(diào)用時(shí),才會(huì)被加載),并在內(nèi)部類中實(shí)例化對(duì)象。
  step3:向外暴露一個(gè)靜態(tài)的公共方法,并在方法中調(diào)用靜態(tài)內(nèi)部類,用于獲取實(shí)例對(duì)象。
(2)代碼實(shí)現(xiàn):

package singleton.pattern.demo7;/** * 演示 單例模式,靜態(tài)內(nèi)部類版 * */public class Demo {    public static void main(String[] args) {        Singleton singleton1 = Singleton.getSingleTon();        Singleton singleton2 = Singleton.getSingleTon();        System.out.println(singleton1 == singleton2); // 由于獲取的為同一個(gè)對(duì)象,所以輸出為true    }}/** * 單例模式,靜態(tài)內(nèi)部類版 */class Singleton {    /**     * 構(gòu)造器私有化(防止通過(guò)new創(chuàng)建實(shí)例對(duì)象)     */    private Singleton() {    }    /**     * 靜態(tài)內(nèi)部類,在被調(diào)用的時(shí)候才會(huì)被加載,實(shí)現(xiàn)懶加載。 且內(nèi)部使用靜態(tài)常量實(shí)例化一個(gè)對(duì)象,保證了線程安全問(wèn)題。     */    public static class SingleTonInstance {        public static final Singleton INSTANCE = new Singleton();    }    /**     * 向外暴露一個(gè)靜態(tài)的公共方法用于獲取實(shí)例對(duì)象,在方法內(nèi)部加個(gè)同步代碼塊,在代碼塊內(nèi)部增加一個(gè)檢查處理。 當(dāng)調(diào)用該方法時(shí),才去檢查并創(chuàng)建一個(gè)實(shí)例對(duì)象。     *      * @return 實(shí)例對(duì)象     */    public static Singleton getSingleTon() {        return SingleTonInstance.INSTANCE; // 調(diào)用靜態(tài)內(nèi)部類的靜態(tài)屬性    }}

(3)優(yōu)缺點(diǎn):
  優(yōu)點(diǎn):利用JVM的類加載機(jī)制,保證了實(shí)例化對(duì)象時(shí)只有一個(gè)線程,從而線程安全。在被調(diào)用時(shí)靜態(tài)內(nèi)部類才會(huì)被加載并實(shí)例化對(duì)象,從而實(shí)現(xiàn)懶加載,效率高。

(4)UML圖:

 

10、枚舉

(1)步驟:
  step1:定義一個(gè)枚舉類型。
  step2:調(diào)用即可
(2)代碼實(shí)現(xiàn):

package singleton.pattern;/** * 演示 單例模式,枚舉版 * */public class Demo {    public static void main(String[] args) {        SingleTon singleton1 = SingleTon.INSTACNE;        SingleTon singleton2 = SingleTon.INSTACNE;        System.out.println(singleton1 == singleton2); // 由于獲取的為同一個(gè)對(duì)象,所以輸出為true    }}/** * 單例模式,枚舉版 */enum SingleTon {    INSTACNE;    public void show() {        System.out.println("hello world");    }}

(3)優(yōu)缺點(diǎn):
  優(yōu)點(diǎn):使用枚舉類型創(chuàng)建(enum本質(zhì)是個(gè)繼承java.lang.Enum類的final class),保證線程安全,且可以防止反序列化重新創(chuàng)建新的對(duì)象。

 

11、JDK中的單例模式舉例(Runtime)

(1)部分源碼

public class Runtime {    private static Runtime currentRuntime = new Runtime();    /**     * Returns the runtime object associated with the current Java application.     * Most of the methods of class <code>Runtime</code> are instance     * methods and must be invoked with respect to the current runtime object.     *     * @return  the <code>Runtime</code> object associated with the current     *          Java application.     */    public static Runtime getRuntime() {        return currentRuntime;    }    /** Don't let anyone else instantiate this class */    private Runtime() {} }

(2)可以看到上述代碼中采用的是 餓漢式單例模式(靜態(tài)變量版)。

12、單例模式使用注意

(1)當(dāng)頻繁創(chuàng)建、銷毀某個(gè)對(duì)象時(shí),可以采用單例模式。
(2)使用單例模式時(shí),需調(diào)用相關(guān)方法獲取實(shí)例,而不是通過(guò)new。
(3)當(dāng)創(chuàng)建對(duì)象消耗資源過(guò)多時(shí),但又經(jīng)常使用時(shí),可以采用單例模式創(chuàng)建。

 

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服