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

9種Java單例模式詳解(推薦)

 更新時(shí)間:2019年03月27日 16:46:47   作者:MRoot  
這篇文章主要介紹了9種Java單例模式詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

單例模式的特點(diǎn)

  1. 一個(gè)類(lèi)只允許產(chǎn)生一個(gè)實(shí)例化對(duì)象。
  2. 單例類(lèi)構(gòu)造方法私有化,不允許外部創(chuàng)建對(duì)象。
  3. 單例類(lèi)向外提供靜態(tài)方法,調(diào)用方法返回內(nèi)部創(chuàng)建的實(shí)例化對(duì)象。

 懶漢式(線(xiàn)程不安全)

其主要表現(xiàn)在單例類(lèi)在外部需要?jiǎng)?chuàng)建實(shí)例化對(duì)象時(shí)再進(jìn)行實(shí)例化,進(jìn)而達(dá)到Lazy Loading 的效果。

通過(guò)靜態(tài)方法 getSingleton() 和private 權(quán)限構(gòu)造方法為創(chuàng)建一個(gè)實(shí)例化對(duì)象提供唯一的途徑。

不足:未考慮到多線(xiàn)程的情況下可能會(huì)存在多個(gè)訪問(wèn)者同時(shí)訪問(wèn),發(fā)生構(gòu)造出多個(gè)對(duì)象的問(wèn)題,所以在多線(xiàn)程下不可用這種方法。

/**
 * @author MrRoot
 * @since 2018-12-17
 * 懶漢式(線(xiàn)程不安全)
 */
public class Singleton {
  private static Singleton singleton;

  private Singleton(){

  }

  public static Singleton singleton(){
    if (singleton == null){
      singleton = new Singleton();
    }
    return singleton;
  }
}

懶漢式(線(xiàn)程安全,同步方法,不推薦使用)

針對(duì)懶漢式的線(xiàn)程不安全,自然會(huì)想到給 getSingleton() 進(jìn)行 synchronized 加鎖來(lái)保證線(xiàn)程同步。

不足:效率低。大多數(shù)情況下這個(gè)鎖占用的額外資源都浪費(fèi)了,每個(gè)線(xiàn)程在想獲得類(lèi)的實(shí)例時(shí)候,執(zhí)行 getSingleton() 方法都要進(jìn)行同步。

/**
 * @author MrRoot
 * @since 2019-3-27
 * 懶漢式(線(xiàn)程安全,同步方法,不推薦使用)
 */
public class Singleton {
  private static Singleton singleton;

  private Singleton(){

  }

  public static synchronized Singleton singleton(){
    if (singleton == null){
      singleton = new Singleton();
    }
    return singleton;
  }

}

餓漢式(線(xiàn)程安全)

在進(jìn)行類(lèi)加載時(shí)完成實(shí)例化對(duì)象的過(guò)程就是餓漢式的形式。

避免了線(xiàn)程同步問(wèn)題,在運(yùn)行這個(gè)類(lèi)的時(shí)候進(jìn)行加載,之后直接訪問(wèn)

不足:相比接下來(lái)的靜態(tài)內(nèi)部類(lèi)而言,這種方法比靜態(tài)內(nèi)部類(lèi)多了內(nèi)存常駐,容易造成內(nèi)存浪費(fèi),也未達(dá)到延遲加載的效果。

/**
 * @author MrRoot
 * @since 2019-3-27
 * 餓漢式(線(xiàn)程安全)
 */
public class Singleton{
  private static Singleton singleton = new Singleton();

  private Singleton(){

  }

  public static Singleton singleton(){
    return singleton;
  }
}

靜態(tài)內(nèi)部類(lèi)加載(線(xiàn)程安全)

靜態(tài)內(nèi)部類(lèi)不會(huì)在單例加載時(shí)加載,當(dāng)調(diào)用 getSingleton() 方法時(shí)才會(huì)進(jìn)行加載,達(dá)到類(lèi)似懶漢式效果,并且也是線(xiàn)程安全的。

類(lèi)的靜態(tài)屬性只會(huì)在第一次加載類(lèi)時(shí)進(jìn)行初始化,所以上面的方法JVM 幫助我們保證了線(xiàn)程的安全性,在類(lèi)進(jìn)行初始化時(shí),其他線(xiàn)程無(wú)法進(jìn)入。

/**
 * @author MrRoot
 * @since 2019-3-27
 * 靜態(tài)內(nèi)部類(lèi)加載(線(xiàn)程安全)
 */
public class Singleton{
  private static Singleton singleton;

  private static class SingletonInner{
    private static final Singleton instance = new Singleton();
  }

  public static Singleton getSingleton(){
    return SingletonInner.instance;
  }
}

枚舉(線(xiàn)程安全)

自由串行化;保證只有一個(gè)實(shí)例;線(xiàn)程安全。

Effective Java 作者所提倡的方法,近乎完美,在繼承場(chǎng)景下不適用。

/**
 * @author MrRoot
 * @since 2019-3-27
 * 枚舉(線(xiàn)程安全)
 */
enum Singleton{
  INSTANCE;

  public void method(){

  }
}

class Test{
  public static void main(String[] args) {
    Singleton.INSTANCE.method();
  }
}

懶漢式雙重校驗(yàn)鎖法(通常線(xiàn)程安全,不可保證完全安全)

使用同步代碼塊避免了第二種方法的效率低的問(wèn)題,但此方法并不能完全起到線(xiàn)程同步的作用,與上面第一種方法產(chǎn)生的問(wèn)題相似,多線(xiàn)程訪問(wèn)時(shí)可能產(chǎn)生多個(gè)對(duì)象。

/**
 * @author MrRoot
 * @since 2019-3-27
 * 懶漢式雙重校驗(yàn)鎖法(通常線(xiàn)程安全,不可保證完全安全)
 */
class Singleton{
  private static Singleton singleton;

  private Singleton(){

  }

  public static Singleton singleton(){
    if (singleton == null){
      synchronized (Singleton.class){
        if (singleton == null){
          singleton = new Singleton();
        }
      }
    }
    return singleton;
  }
}

懶漢式雙重檢查終極版

與第六種方法不同的是,此方法給singleton 的聲明上加了關(guān)鍵字 volatile ,進(jìn)而解決了低概率的線(xiàn)程不安全問(wèn)題。

volatile 起到禁止指令重排的作用,在它賦值完成之前,就不會(huì)調(diào)用讀操作(singleton == null)。

/**
 * @author MrRoot
 * @since 2019-3-27
 * 懶漢式雙重檢查終極版(volatile)
 */
class Singleton{
  private static volatile Singleton singleton;

  private Singleton(){

  }

  public static Singleton singleton(){
    if (singleton == null){
      synchronized (Singleton.class){
        if (singleton == null){
          singleton = new Singleton();
        }
      }
    }
    return singleton;
  }
}

使用 ThreadLocal 實(shí)現(xiàn)(線(xiàn)程安全)

ThreadLocal 會(huì)為每一個(gè)線(xiàn)程提供一個(gè)獨(dú)立的變量副本,從而隔離了多個(gè)線(xiàn)程對(duì)數(shù)據(jù)的訪問(wèn)沖突。

對(duì)于多線(xiàn)程資源共享的問(wèn)題,同步機(jī)制采用了“以時(shí)間換空間”的方式,而ThreadLocal 采用了“以空間換時(shí)間”的方式。前者僅提供一份變量,讓不同的線(xiàn)程排隊(duì)訪問(wèn),而后者為每一個(gè)線(xiàn)程都提供了一份變量,因此可以同時(shí)訪問(wèn)而互不影響。

/**
 * @author MrRoot
 * @since 2019-3-27
 * 使用 ThreadLocal 實(shí)現(xiàn)(線(xiàn)程安全)
 */
class Singleton{
  private static final ThreadLocal<Singleton> singleton = new
      ThreadLocal<Singleton>(){
        @Override
        protected Singleton initialValue(){
          return new Singleton();
        }
      };

  private Singleton(){

  }

  public static Singleton getSingleton(){
    return singleton.get();
  }
}

使用CAS 鎖實(shí)現(xiàn)(線(xiàn)程安全)

/**
 * @author MrRoot
 * @since 2019-3-27
 * 使用 CAS 實(shí)現(xiàn)(線(xiàn)程安全)
 */
public class Singleton {
  private static final AtomicReference<Singleton> INSTANCE = new AtomicReference<Singleton>();

  private Singleton(){

  }

  public static final Singleton getSingleton(){
    for (;;){
      Singleton current = INSTANCE.get();
      if (current != null){
        return current;
      }
      current = new Singleton();
      if (INSTANCE.compareAndSet(null,current)){
        return current;
      }
    }
  }

  public static void main(String[] args) {
    Singleton singleton1 = Singleton.getSingleton();
    Singleton singleton2 = Singleton.getSingleton();
    System.out.println(singleton1 == singleton2);
  }
}

以上所述是小編給大家介紹的9種Java單例模式詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • Java設(shè)計(jì)模式之代理模式與裝飾模式實(shí)例詳解

    Java設(shè)計(jì)模式之代理模式與裝飾模式實(shí)例詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式之代理模式與裝飾模式,結(jié)合具體實(shí)例形式分析了代理模式與裝飾模式的概念、功能、java實(shí)現(xiàn)方法與相關(guān)使用注意事項(xiàng),需要的朋友可以參考下
    2017-09-09
  • IDEA 2020.2 部署JSF項(xiàng)目的詳細(xì)過(guò)程

    IDEA 2020.2 部署JSF項(xiàng)目的詳細(xì)過(guò)程

    本文通過(guò)圖文并茂的形式教大家如何在IDEA中創(chuàng)建一個(gè)JSF項(xiàng)目及遇到問(wèn)題的解決方法,感興趣的朋友跟隨小編一起看看吧
    2021-09-09
  • Java類(lèi)鎖、對(duì)象鎖、私有鎖沖突測(cè)試

    Java類(lèi)鎖、對(duì)象鎖、私有鎖沖突測(cè)試

    這篇文章主要介紹了Java類(lèi)鎖、對(duì)象鎖、私有鎖沖突測(cè)試,得出結(jié)論是加鎖方法夠成了競(jìng)爭(zhēng)關(guān)系,同一時(shí)刻只能有一個(gè)方法能執(zhí)行,需要的朋友可以參考下
    2014-10-10
  • 通過(guò)Java修改游戲存檔的實(shí)現(xiàn)思路

    通過(guò)Java修改游戲存檔的實(shí)現(xiàn)思路

    這篇文章主要介紹了通過(guò)Java修改游戲存檔的實(shí)現(xiàn)思路,實(shí)現(xiàn)方法也很簡(jiǎn)單,因?yàn)橹参锎髴?zhàn)僵尸游戲的數(shù)據(jù)文件存儲(chǔ)在本地的存儲(chǔ)位置是已知的,因此我們可以將實(shí)現(xiàn)過(guò)程拆分為三個(gè)步驟,需要的朋友可以參考下
    2021-10-10
  • Java?for循環(huán)標(biāo)簽跳轉(zhuǎn)到指定位置的示例詳解

    Java?for循環(huán)標(biāo)簽跳轉(zhuǎn)到指定位置的示例詳解

    這篇文章主要介紹了Java?for循環(huán)標(biāo)簽跳轉(zhuǎn)到指定位置,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-05-05
  • maven項(xiàng)目pom.xml中parent標(biāo)簽的使用小結(jié)

    maven項(xiàng)目pom.xml中parent標(biāo)簽的使用小結(jié)

    使用maven是為了更好的幫項(xiàng)目管理包依賴(lài),maven的核心就是pom.xml,當(dāng)我們需要引入一個(gè)jar包時(shí),在pom文件中加上就可以從倉(cāng)庫(kù)中依賴(lài)到相應(yīng)的jar包,本文就來(lái)介紹一下maven項(xiàng)目pom.xml中parent標(biāo)簽的使用小結(jié),感興趣的可以了解一下
    2023-12-12
  • java實(shí)現(xiàn)解析json復(fù)雜數(shù)據(jù)的方法詳解

    java實(shí)現(xiàn)解析json復(fù)雜數(shù)據(jù)的方法詳解

    這篇文章主要為大家詳細(xì)介紹了java如何實(shí)現(xiàn)解析json復(fù)雜數(shù)據(jù),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以學(xué)習(xí)一下
    2024-01-01
  • 一文詳解如何查看jdk版本及安裝路徑

    一文詳解如何查看jdk版本及安裝路徑

    這篇文章主要給大家介紹了關(guān)于如何查看jdk版本及安裝路徑的相關(guān)資料,JDK是Java語(yǔ)言的軟件開(kāi)發(fā)工具包,主要用于移動(dòng)設(shè)備、嵌入式設(shè)備上的java應(yīng)用程序,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • springboot中RestTemplate發(fā)送HTTP請(qǐng)求的實(shí)現(xiàn)示例

    springboot中RestTemplate發(fā)送HTTP請(qǐng)求的實(shí)現(xiàn)示例

    RestTemplate是一個(gè) spring-web 提供的執(zhí)行HTTP請(qǐng)求的同步阻塞式工具類(lèi),本文就來(lái)介紹一下RestTemplate發(fā)送HTTP請(qǐng)求,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Java獲取接口所有實(shí)現(xiàn)類(lèi)的方式詳解

    Java獲取接口所有實(shí)現(xiàn)類(lèi)的方式詳解

    這篇文章主要介紹了Java獲取接口所有實(shí)現(xiàn)類(lèi)的方式詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12

最新評(píng)論

浠水县| 昌图县| 读书| 永修县| 乌审旗| 牟定县| 阿图什市| 庆城县| 普宁市| 喜德县| 大渡口区| 沧源| 历史| 陵水| 林西县| 元氏县| 平利县| 开鲁县| 蒙自县| 襄樊市| 新余市| 通州区| 蓬溪县| 太仆寺旗| 大港区| 府谷县| 兴文县| 农安县| 大埔县| 克什克腾旗| 武平县| 威信县| 巴林右旗| 长宁县| 鄂温| 兴海县| 获嘉县| 雅江县| 深泽县| 临安市| 武鸣县|