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

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

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

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

常用:

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

其他:

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

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

以上的單例模式就不測(cè)試,大家可以去測(cè)試,判斷對(duì)象的hashcode是否一致來(lái)判斷是否為同一個(gè)對(duì)象。

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

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

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; 
 
/** 
 * 懶漢漢式單例,在需要單例對(duì)象的時(shí)候,才創(chuàng)建唯一的單例對(duì)象,以后再次調(diào)用,返回的也是第一創(chuàng)建的單例對(duì)象 
 * 將靜態(tài)成員初始化為null,在獲取單例的時(shí)候才創(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() { 
    /** 
     * 防止反射攻擊,只運(yùn)行調(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)上說(shuō)的 雙重檢查加鎖的方法 
   * @return 
   */ 
  public static synchronized Singleton getInstance(){ 
    if(instance==null){ 
      synchronized (Singleton.class) { 
        if(instance==null){ 
          instance = new Singleton(); 
        } 
      } 
    } 
    return instance; 
  } 
  /** 
   * 
   * 防止反序列生成新的單例對(duì)象,這是effective Java 一書中說(shuō)的用此方法可以防止,具體細(xì)節(jié)我也不明白 
   * @return 
   */ 
  private Object readResolve(){ 
    return instance; 
  } 
  public static void main(String[] args) throws Exception { 
    test1(); 
    test2(); 
  } 
  /** 
   * 測(cè)試 反序列 仍然為單例模式 
   * @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(); 
  } 
  /** 
   * 測(cè)試反射攻擊 
   * @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(); 
    } 
  } 
} 

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

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

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

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

相關(guān)文章

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

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

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

    Java中Equals使用方法匯總

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

    Spring cloud config 配置文件加密方式

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

    Java8 中的ParallelStream

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

    Spring?Bean后處理器詳細(xì)介紹

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

    SpringBoot WebSocket連接報(bào)no mapping for GE

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

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

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

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

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

    Java?OkHttp框架源碼超詳細(xì)解析

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

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

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

最新評(píng)論

富裕县| 荃湾区| 辉县市| 宜兴市| 环江| 罗田县| 苏州市| 汉阴县| 平江县| 观塘区| 嵊泗县| 章丘市| 甘泉县| 绥中县| 松滋市| 汕尾市| 大足县| 雅江县| 岳阳市| 镇平县| 光山县| 景德镇市| 黄陵县| 安西县| 台北县| 乐亭县| 顺义区| 柳江县| 枣强县| 盐亭县| 扎赉特旗| 阳春市| 屯门区| 蓬溪县| 阳城县| 自贡市| 河北省| 安平县| 兰溪市| 水富县| 乌拉特后旗|