最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA破壞單例模式的方式以及避免方法

 更新時(shí)間:2020年06月16日 11:32:04   作者:宋者為王  
這篇文章主要介紹了JAVA破壞單例模式的方式以及避免方法,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下

      單例模式,大家恐怕再熟悉不過(guò)了,其作用與實(shí)現(xiàn)方式有多種,這里就不啰嗦了。但是,咱們?cè)谑褂眠@些方式實(shí)現(xiàn)單例模式時(shí),程序中就真的會(huì)只有一個(gè)實(shí)例嗎?

      聰明的你看到這樣的問(wèn)話(huà),一定猜到了答案是NO。這里筆者就不賣(mài)關(guān)子了,開(kāi)門(mén)見(jiàn)山吧!實(shí)際上,在有些場(chǎng)景下,如果程序處理不當(dāng),會(huì)無(wú)情地破壞掉單例模式,導(dǎo)致程序中出現(xiàn)多個(gè)實(shí)例對(duì)象。

      下面筆者介紹筆者已知的三種破壞單例模式的方式以及避免方法。

1、反射對(duì)單例模式的破壞

      我們先通過(guò)一個(gè)例子,來(lái)直觀(guān)感受一下

    (1)案例

  DCL實(shí)現(xiàn)的單例模式:

public class Singleton{
  private static volatile Singleton mInstance;
  private Singleton(){}
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
}

測(cè)試代碼:

public class SingletonDemo {

  public static void main(String[] args){
    Singleton singleton = Singleton.getInstance();
    try {
      Constructor<Singleton> constructor = Singleton.class.getDeclaredConstructor();
      constructor.setAccessible(true);
      Singleton reflectSingleton = constructor.newInstance();
      System.out.println(reflectSingleton == singleton);
    } catch (Exception e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

執(zhí)行結(jié)果:

false

      運(yùn)行結(jié)果說(shuō)明,采用反射的方式另辟蹊徑實(shí)例了該類(lèi),導(dǎo)致程序中會(huì)存在不止一個(gè)實(shí)例。

    (2)解決方案

      其思想就是采用一個(gè)全局變量,來(lái)標(biāo)記是否已經(jīng)實(shí)例化過(guò)了,如果已經(jīng)實(shí)例化過(guò)了,第二次實(shí)例化的時(shí)候,拋出異常。實(shí)現(xiàn)代碼如下:

public class Singleton{
  private static volatile Singleton mInstance;
  private static volatile boolean mIsInstantiated = false;
  private Singleton(){
    if (mIsInstantiated){
      throw new RuntimeException("Has been instantiated, can not do it again!");
    }
    mIsInstantiated = true;
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
}

執(zhí)行結(jié)果:

2、clone()對(duì)單例模式的破壞

       當(dāng)需要實(shí)現(xiàn)單例的類(lèi)允許clone()時(shí),如果處理不當(dāng),也會(huì)導(dǎo)致程序中出現(xiàn)不止一個(gè)實(shí)例。

    (1)案例

  一個(gè)實(shí)現(xiàn)了Cloneable接口單例類(lèi):

public class Singleton implements Cloneable{
  private static volatile Singleton mInstance;
  private Singleton(){
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
  @Override
  protected Object clone() throws CloneNotSupportedException {
    // TODO Auto-generated method stub
    return super.clone();
  }
}

測(cè)試代碼:

public class SingletonDemo {

  public static void main(String[] args){
    try {
      Singleton singleton = Singleton.getInstance();
      Singleton cloneSingleton;
      cloneSingleton = (Singleton) Singleton.getInstance().clone();
      System.out.println(cloneSingleton == singleton);
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
  }
}

執(zhí)行結(jié)果:

false

  (2)解決方案:

     解決思想是,重寫(xiě)clone()方法,調(diào)clone()時(shí)直接返回已經(jīng)實(shí)例的對(duì)象

public class Singleton implements Cloneable{
  private static volatile Singleton mInstance;
  private Singleton(){
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
  @Override
  protected Object clone() throws CloneNotSupportedException {
    return mInstance;
  }
}

執(zhí)行結(jié)果:

true

3、序列化對(duì)單例模式的破壞

   在使用序列化/反序列化時(shí),也會(huì)出現(xiàn)產(chǎn)生新實(shí)例對(duì)象的情況。

  (1)案例

      一個(gè)實(shí)現(xiàn)了序列化接口的單例類(lèi):

public class Singleton implements Serializable{
  private static volatile Singleton mInstance;
  private Singleton(){
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }
}

測(cè)試代碼:

public class SingletonDemo {

  public static void main(String[] args){
    try {
      Singleton singleton = Singleton.getInstance();
      FileOutputStream fos = new FileOutputStream("singleton.txt");
      ObjectOutputStream oos = new ObjectOutputStream(fos);
      oos.writeObject(singleton);
      oos.close();
      fos.close();

      FileInputStream fis = new FileInputStream("singleton.txt");
      ObjectInputStream ois = new ObjectInputStream(fis);
      Singleton serializedSingleton = (Singleton) ois.readObject();
      fis.close();
      ois.close();
      System.out.println(serializedSingleton==singleton);
    } catch (Exception e) {
      e.printStackTrace();
    }

  }
}

     運(yùn)行結(jié)果:

false

    (2)解決方案

    在反序列化時(shí)的回調(diào)方法 readResolve()中返回單例對(duì)象。

public class Singleton implements Serializable{
  private static volatile Singleton mInstance;
  private Singleton(){
  }
  public static Singleton getInstance(){
    if(mInstance == null){
      synchronized (Singleton.class) {
        if(mInstance == null){
          mInstance = new Singleton();
        }
      }
    }
    return mInstance;
  }

  protected Object readResolve() throws ObjectStreamException{
    return mInstance;
  }
}

結(jié)果:

true

       以上就是筆者目前已知的三種可以破壞單例模式的場(chǎng)景以及對(duì)應(yīng)的解決辦法,讀者如果知道還有其他的場(chǎng)景,記得一定要分享出來(lái)噢,正所謂“獨(dú)樂(lè)樂(lè)不如眾樂(lè)樂(lè)”?。?!

       單例模式看起來(lái)是設(shè)計(jì)模式中最簡(jiǎn)單的一個(gè),但“麻雀雖小,五臟俱全”,其中有很多細(xì)節(jié)都是值得深究的。即便是本篇介紹的這幾個(gè)場(chǎng)景,也只是介紹了一些梗概而已,很多細(xì)節(jié)還需要讀者自己去試驗(yàn)和推敲的,比如:通過(guò)枚舉方式實(shí)現(xiàn)單例模式,就不存在上述問(wèn)題,而其它的實(shí)現(xiàn)方式似乎都存在上述問(wèn)題!

       后記

       本篇參(剽)考(竊)了如下資料:http://www.fzitv.net/article/143047.htm

以上就是JAVA破壞單例模式的方式以及避免方法的詳細(xì)內(nèi)容,更多關(guān)于JAVA 單例模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

涪陵区| 吉水县| 瑞安市| 出国| 龙江县| 诏安县| 河源市| 乌拉特后旗| 诏安县| 巴南区| 安新县| 东莞市| 逊克县| 防城港市| 民勤县| 墨竹工卡县| 久治县| 高阳县| 高雄县| 呼伦贝尔市| 临夏县| 徐水县| 隆安县| 威远县| 长汀县| 水城县| 泊头市| 阳高县| 广汉市| 大连市| 买车| 深水埗区| 衡阳县| 万州区| 清水河县| 天门市| 汽车| 陆良县| 绿春县| 仲巴县| 辽阳市|