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

Java實現(xiàn)單例模式之餓漢式、懶漢式、枚舉式

 更新時間:2016年10月25日 15:08:32   作者:我只是一名程序員  
本篇文章主要介紹了Java實現(xiàn)單例的3種普遍的模式,餓漢式、懶漢式、枚舉式。具有一定的參考價值,感興趣的小伙伴們可以參考一下。

單例模式的實現(xiàn)(5種)

常用:

餓漢式(線程安全,調(diào)用效率高,但是不能延時加載)
懶漢式(線程安全,調(diào)用效率不高,可以延時加載)

其他:

雙重檢測鎖式(由于jvm底層內(nèi)部模型原因,偶爾會出問題,不建立使用)
靜態(tài)內(nèi)部類式(線程安全,調(diào)用效率高,但是可以延時加載)
枚舉單例(線程安全,調(diào)用效率高,不能延時加載)
餓漢式單例具體代碼如下:

package com.lcx.mode; 
 
 
/** 
 * 
 * 餓漢式單例,不管以后用不用這個對象,我們一開始就創(chuàng)建這個對象的實例, 
 * 需要的時候就返回已創(chuàng)建好的實例對象,所以比較饑餓,故此叫餓漢式單例。 
 * @author qq1013985957 
 * 
 */ 
public class SingletonHanger { 
  private static final SingletonHanger instance = new SingletonHanger(); 
  private SingletonHanger() { 
  } 
  public static SingletonHanger getInstance(){ 
    return instance; 
  } 
} 
/** 
 * 懶漢漢式單例,在需要單例對象的時候,才創(chuàng)建唯一的單例對象,以后再次調(diào)用,返回的也是第一創(chuàng)建的單例對象 
 * 將靜態(tài)成員初始化為null,在獲取單例的時候才創(chuàng)建,故此叫懶漢式。 
 * @author qq1013985957 
 * 
 */ 
class SingletonLazy{ 
  private static SingletonLazy instance = null; 
  private SingletonLazy() { 
  } 
  /** 
   * 此方法實現(xiàn)的單例,無法在多線程中使用,多線可以同時進入if方法,會導致生成多個單例對象。 
   * @return 
   */ 
  public static SingletonLazy getInstance1(){ 
    if(instance==null){ 
      instance = new SingletonLazy(); 
    } 
    return instance; 
  } 
  /** 
   * 大家都會想到同步,可以同步方法實現(xiàn)多線程的單例 
   * 但是這種方法不可取,嚴重影響性能,因為每次去取單例都要檢查方法,所以只能用同步代碼塊的方式實現(xiàn)同步。 
   * @return 
   */ 
  public static synchronized SingletonLazy getInstance2(){ 
    if(instance==null){ 
      instance = new SingletonLazy(); 
    } 
    return instance; 
  } 
  /** 
   * 用同步代碼塊的方式,在判斷單例是否存在的if方法里使用同步代碼塊,在同步代碼塊中再次檢查是否單例已經(jīng)生成, 
   * 這也就是網(wǎng)上說的 雙重檢查加鎖的方法 
   * @return 
   */ 
  public static synchronized SingletonLazy getInstance3(){ 
    if(instance==null){ 
      synchronized (SingletonLazy.class) { 
        if(instance==null){ 
          instance = new SingletonLazy(); 
        } 
      } 
    } 
    return instance; 
  } 
} 
/** 
 * 
 * 使用枚舉實現(xiàn)單例模式,也是Effective Java中推薦使用的方式 
 * 根據(jù)具體情況進行實例化,對枚舉不熟悉的同學,可以參考我的博客 JAVA 枚舉類的初步理解。 
 * 它的好處:更加簡潔,無償提供了序列化機制,絕對防止多次實例化,即使面對復雜的序列和反射攻擊。 
 * @author qq1013985957 
 * 
 */ 
enum SingletionEnum{ 
  SingletionEnum("單例的枚舉方式"); 
  private String str ; 
  private SingletionEnum(String str){ 
    this.setStr(str); 
  } 
  public String getStr() { 
    return str; 
  } 
  public void setStr(String str) { 
    this.str = str; 
  } 
   
} 

以上的單例模式就不測試,大家可以去測試,判斷對象的hashcode是否一致來判斷是否為同一個對象。

惡漢式、懶漢式的方式還不能防止反射來實現(xiàn)多個實例,通過反射的方式,設置ACcessible.setAccessible方法可以調(diào)用私有的構(gòu)造器,可以修改構(gòu)造器,讓它在被要求創(chuàng)建第二個實例的時候拋出異常。

其實這樣還不能保證單例,當序列化后,反序列化是還可以創(chuàng)建一個新的實例,在單例類中添加readResolve()方法進行防止。
懶漢漢式單例代碼如下:

package com.lcx.mode; 
 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 
import java.lang.reflect.Constructor; 
import java.lang.reflect.InvocationTargetException; 
 
/** 
 * 懶漢漢式單例,在需要單例對象的時候,才創(chuàng)建唯一的單例對象,以后再次調(diào)用,返回的也是第一創(chuàng)建的單例對象 
 * 將靜態(tài)成員初始化為null,在獲取單例的時候才創(chuàng)建,故此叫懶漢式。 
 * @author qq1013985957 
 * 
 */ 
public class Singleton implements Serializable{ 
  /** 
   * 
   */ 
  private static final long serialVersionUID = -5271537207137321645L; 
  private static Singleton instance = null; 
  private static int i = 1; 
  private Singleton() { 
    /** 
     * 防止反射攻擊,只運行調(diào)用一次構(gòu)造器,第二次拋異常 
     */ 
    if(i==1){ 
      i++; 
    }else{ 
      throw new RuntimeException("只能調(diào)用一次構(gòu)造函數(shù)"); 
    } 
    System.out.println("調(diào)用Singleton的私有構(gòu)造器"); 
     
  } 
  /** 
   * 用同步代碼塊的方式,在判斷單例是否存在的if方法里使用同步代碼塊,在同步代碼塊中再次檢查是否單例已經(jīng)生成, 
   * 這也就是網(wǎng)上說的 雙重檢查加鎖的方法 
   * @return 
   */ 
  public static synchronized Singleton getInstance(){ 
    if(instance==null){ 
      synchronized (Singleton.class) { 
        if(instance==null){ 
          instance = new Singleton(); 
        } 
      } 
    } 
    return instance; 
  } 
  /** 
   * 
   * 防止反序列生成新的單例對象,這是effective Java 一書中說的用此方法可以防止,具體細節(jié)我也不明白 
   * @return 
   */ 
  private Object readResolve(){ 
    return instance; 
  } 
  public static void main(String[] args) throws Exception { 
    test1(); 
    test2(); 
  } 
  /** 
   * 測試 反序列 仍然為單例模式 
   * @throws Exception 
   */ 
  public static void test2() throws Exception{ 
    Singleton s = Singleton.getInstance(); 
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(new File("E:\\Singleton.txt"))); 
    objectOutputStream.writeObject(s); 
    ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(new File("E:\\Singleton.txt"))); 
    Object readObject = objectInputStream.readObject(); 
    Singleton s1 = (Singleton)readObject; 
    System.out.println("s.hashCode():"+s.hashCode()+",s1.hashCode():"+s1.hashCode()); 
     
    objectOutputStream.flush(); 
    objectOutputStream.close(); 
    objectInputStream.close(); 
  } 
  /** 
   * 測試反射攻擊 
   * @throws Exception 
   */ 
  public static void test1(){ 
    Singleton s = Singleton.getInstance(); 
    Class c = Singleton.class; 
    Constructor privateConstructor; 
    try { 
      privateConstructor = c.getDeclaredConstructor(); 
      privateConstructor.setAccessible(true); 
      privateConstructor.newInstance(); 
    } catch (Exception e) { 
      e.printStackTrace(); 
    } 
  } 
} 

驗證反射攻擊結(jié)果:

如果不添加readResolve方法的結(jié)果:

添加readResolve方法的結(jié)果:

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關文章

  • Java實現(xiàn)添加、驗證PDF數(shù)字簽名的方法示例

    Java實現(xiàn)添加、驗證PDF數(shù)字簽名的方法示例

    在設置文檔內(nèi)容保護的方法中,除了對文檔加密、添加水印外,應用數(shù)字簽名也是一種有效防偽手段。本文就使用Java實現(xiàn)添加、驗證PDF數(shù)字簽名,感興趣的可以了解一下
    2021-07-07
  • Java中Equals使用方法匯總

    Java中Equals使用方法匯總

    這篇文章主要采用問答的方式集中講解了Java中Equals的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • Spring cloud config 配置文件加密方式

    Spring cloud config 配置文件加密方式

    這篇文章給大家介紹了Spring cloud config 配置文件加密方式,非常不錯,具有一定的參考借鑒價值,感興趣的朋友跟隨腳步之家小編一起學習吧
    2018-05-05
  • Java8 中的ParallelStream

    Java8 中的ParallelStream

    這篇文章主要介紹了Java8 中的并行流 ParallelStreams,Java8并行流ParallelStream和Stream的區(qū)別就是支持并行執(zhí)行,提高程序運行效率。下面就來看看文章內(nèi)容具體介紹吧
    2021-10-10
  • Spring?Bean后處理器詳細介紹

    Spring?Bean后處理器詳細介紹

    Bean后置處理器允許在調(diào)用初始化方法前后對Bean進行額外的處理??梢栽?Spring容器通過插入一個或多個BeanPostProcessor的實現(xiàn)來完成實例化,配置和初始化一個?bean?之后實現(xiàn)一些自定義邏輯回調(diào)方法
    2023-01-01
  • SpringBoot WebSocket連接報no mapping for GET問題

    SpringBoot WebSocket連接報no mapping for GE

    文章描述了一個在調(diào)試WebSocket連接時遇到的`nomappingforGET`異常問題,并提供了問題解決的方法,包括檢查WebSocket注解和補充相關配置,此外,還特別提到了在使用Nginx轉(zhuǎn)發(fā)WebSocket時所需的配置
    2025-02-02
  • 一篇文章帶你入門Java方法詳解

    一篇文章帶你入門Java方法詳解

    這篇文章主要介紹了簡單了解Java方法的定義和使用實現(xiàn)詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2021-08-08
  • java+jdbc+mysql+socket搭建局域網(wǎng)聊天室

    java+jdbc+mysql+socket搭建局域網(wǎng)聊天室

    這篇文章主要為大家詳細介紹了java+jdbc+mysql+socket搭建局域網(wǎng)聊天室,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • Java?OkHttp框架源碼超詳細解析

    Java?OkHttp框架源碼超詳細解析

    okhttp是一個第三方類庫,用于android中請求網(wǎng)絡。這是一個開源項目,是安卓端最火熱的輕量級框架,由移動支付Square公司貢獻(該公司還貢獻了Picasso和LeakCanary)?。用于替代HttpUrlConnection和Apache?HttpClient
    2022-11-11
  • java實現(xiàn)短地址服務的方法(附代碼)

    java實現(xiàn)短地址服務的方法(附代碼)

    大多數(shù)情況下URL太長,字符多,不便于發(fā)布復制和存儲,本文就介紹了通過java實現(xiàn)短地址服務,減少了許多使用太長URL帶來的不便,需要的朋友可以參考下
    2015-07-07

最新評論

山西省| 甘孜县| 航空| 湘乡市| 潼南县| 永登县| 柏乡县| 松阳县| 宁波市| 铜陵市| 肥乡县| 孟连| 博客| 馆陶县| 敦煌市| 徐水县| 山阳县| 元阳县| 镇原县| 团风县| 太仓市| 泸溪县| 溧阳市| 西盟| 扶绥县| 筠连县| 白河县| 天门市| 讷河市| 甘孜县| 徐闻县| 怀化市| 藁城市| 昂仁县| 尤溪县| 滁州市| 启东市| 洪泽县| 仙居县| 万山特区| 龙岩市|