單例模式

單例模式

單件:

獨(dú)一無二,他是利用單件模式構(gòu)造出來的,這個(gè)模式讓讓他在任何時(shí)刻都是只有一個(gè)對象,比如:如果注冊表設(shè)置的對象,不想這樣的對象有多個(gè)拷貝,就可以用單例模式,確保程序中使用的全局資源只有一份。

常常被用來管理共享資源,例如數(shù)據(jù)連接或者線程池

單例類擁有以下幾個(gè)要素:

  • 私有構(gòu)造方法(保證客戶端無法去實(shí)例化該對象)
  • 指向自己實(shí)例的私有靜態(tài)引用
  • 以自己實(shí)例為返回值得靜態(tài)的共有的方法

單例模式分類

A、懶漢單例模式:在第一次調(diào)用的時(shí)候?qū)嵗旧?,在并發(fā)環(huán)境下,可能出現(xiàn)多個(gè)本身對象。所以線程是不安全的

B、餓漢單例模式:在類初始化時(shí),已經(jīng)自行實(shí)例化一個(gè)靜態(tài)對象,所以本身就是線程安全的

C、登記單例模式:通過一個(gè)專門的類對各單例模式的單一實(shí)例進(jìn)行管理和維護(hù)

詳細(xì)說明 (推薦餓漢式)

1.懶漢寫法:如果getInstance()的性能對應(yīng)用程序不是很關(guān)鍵,就什么都別做</p>

public class Singleton_1 {

    public static void main(String[] args) {
        Singleton_1 singleton_11 = Singleton_1.getSingleton_1();
        Singleton_1 singleton_12 = Singleton_1.getSingleton_1();
        System.out.println(singleton_11);
        System.out.println(singleton_12);
    }
    private  static Singleton_1 singleton_1 = null;

    private Singleton_1(){}

    public static Singleton_1 getSingleton_1(){
        if (singleton_1 == null){
            singleton_1 = new Singleton_1();
        }
        return  singleton_1;
    }
}

這種方式在多線程的情況下并不實(shí)用
下面測試:

/**
 * Singleton 這種方式之適合單線程的狀態(tài)
 * com.offer.demo.singleton.Singleton_1@5c25cea
 * com.offer.demo.singleton.Singleton_1@3c13f478
 * com.offer.demo.singleton.Singleton_1@3c13f478
 */
public class Singleton_1_Test {
    public static void main(String[] args) {
        Thread thead1 = new Thread(new Runnable() {
            public void run() {
                Singleton_1  singleton_1 =Singleton_1.getSingleton_1();
                System.out.println(singleton_1);
            }
        });

        Thread thead2 = new Thread(new Runnable() {
            public void run() {
                Singleton_1  singleton_2 =Singleton_1.getSingleton_1();
                System.out.println(singleton_2);
            }
        });
        Thread thead3 = new Thread(new Runnable() {
            public void run() {
                Singleton_1  singleton_3 =Singleton_1.getSingleton_1();
                System.out.println(singleton_3);
            }
        });

        thead1.start();
        thead2.start();
        thead3.start();

    }
}

2.使用急切創(chuàng)建實(shí)例,而不是用延遲實(shí)例化的方法。這種方式也叫做餓漢式的單例模式

public class Singleton_2 {

    public static void main(String[] args) {

        Singleton_2 singleton_1 = Singleton_2.getSingleton_2();
        Singleton_2 singleton_12 = Singleton_2.getSingleton_2();
        System.out.println(singleton_1);
        System.out.println(singleton_12);
    }

    private  static Singleton_2 singleton_2 = new Singleton_2();

    private Singleton_2(){}

    public static Singleton_2 getSingleton_2(){
        return singleton_2;
    }
}

測試類:

/**
 * 餓漢式適合多線程的情況
 *
 * com.offer.demo.singleton.Singleton_2@7bddc905
 * com.offer.demo.singleton.Singleton_2@7bddc905
 * com.offer.demo.singleton.Singleton_2@7bddc905
 */
public class Singleton_2_Test {
    public static void main(String[] args) {
        Thread thead1 = new Thread(new Runnable() {
            public void run() {
               Singleton_2 singleton_1 = Singleton_2.getSingleton_2();
                System.out.println(singleton_1);
            }
        });

        Thread thead2 = new Thread(new Runnable() {
            public void run() {
                Singleton_2  singleton_2 =Singleton_2.getSingleton_2();
                System.out.println(singleton_2);
            }
        });
        Thread thead3 = new Thread(new Runnable() {
            public void run() {
                Singleton_2  singleton_3 =Singleton_2.getSingleton_2();
                System.out.println(singleton_3);
            }
        });

        thead1.start();
        thead2.start();
        thead3.start();

    }
}

3.用"雙重檢查加鎖",首先檢查是否實(shí)例已經(jīng)創(chuàng)建,如果尚未創(chuàng)建,才進(jìn)行同步,這里一來,只有第一次同步,這正是我們想要的。

1. public class SingletonTest3 {
  2.    //在靜態(tài)初始化器中創(chuàng)建單例,這段代碼保證了線程安全
  3.    private volatile static SingletonTest3 uniqueInstance;
  4.     //這里吧構(gòu)造器申明為私有的,只有自Singleton類內(nèi)才可以調(diào)用構(gòu)造器
  5.     private SingletonTest3(){}
  6.     //用getInstance方法實(shí)例化對象,并返回這個(gè)實(shí)例
  7.     public static SingletonTest3 getInstance(){
  8.        if(uniqueInstance==null){
  9.            synchronized (SingletonTest3.class){
  10.        if(uniqueInstance ==null){
  11.              uniqueInstance=new SingletonTest3();
  12.          }}}
  13.        //已經(jīng)有了實(shí)例了,直接使用它。
  14.         return uniqueInstance;
  15.     }
  16. }

4.類加載的方式:延遲加載,線程安全,同步情況下效率高,不要進(jìn)行同步控制,實(shí)現(xiàn)簡單,不能防止反序列化

1. package designpattern.signleton;
  2. /**
      單例模式,類加載方式
  8.  */
  9. public class SingletonTest4 {
  10.   
  11.    //這里吧構(gòu)造器申明為私有的,只有自Singleton類內(nèi)才可以調(diào)用構(gòu)造器
  12.     private SingletonTest4(){}
  13.    
  14.     //靜態(tài)內(nèi)部類,用于持有唯一的SingletonClass的實(shí)例
  15.     private static class OnlyInstance{
  16.       static private SingletonTest4 ONLY=new SingletonTest4();
  17.     }
  18.     
  19.     public static SingletonTest4 getInstance(){
  20.       return OnlyInstance.ONLY;
  21.     }
  22. }

5.枚舉方式:立即加載,線程安全,實(shí)現(xiàn)簡單,防止反序列化。

1. public enum SingletonTest5 {
  2.    
  3.    INSRANCE;
  4.    public void f(){
  5.    }
  6. }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡單、最易理解的設(shè)計(jì)模式,也因?yàn)樗暮啙嵰锥?,是?xiàng)目中最...
    成熱了閱讀 4,544評論 4 34
  • 1 場景問題# 1.1 讀取配置文件的內(nèi)容## 考慮這樣一個(gè)應(yīng)用,讀取配置文件的內(nèi)容。 很多應(yīng)用項(xiàng)目,都有與應(yīng)用相...
    七寸知架構(gòu)閱讀 6,976評論 12 68
  • 1.單例模式概述 (1)引言 單例模式是應(yīng)用最廣的模式之一,也是23種設(shè)計(jì)模式中最基本的一個(gè)。本文旨在總結(jié)通過Ja...
    曹豐斌閱讀 3,071評論 6 47
  • 薄暮遲黃昏,衣錦路歸人。 臨山聞犬吠,清煙伴笑聲。 我有一個(gè)好習(xí)慣那就是曾經(jīng)在筆記本里寫下很多只言片語,聽說李白之...
    楊婼_閱讀 237評論 0 0
  • 今天拖FMDB進(jìn)工程里出了這么個(gè)問題,用網(wǎng)上第一種方法解決。 改動(dòng)info.plist 如下即可: ------mark
    水煮杰尼龜閱讀 1,249評論 0 0

友情鏈接更多精彩內(nèi)容