<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                # 單例模式 單例模式有非常多種的實現方式,具體如下: ## 餓漢式 - 靜態常量 ~~~ ?package cn.net.smrobot.singleton.type1; ?? ?/** ? * 餓漢式,使用靜態變量的方式 ? */ ?public class Singleton { ?? ? ? ?/** ? ? ? * 將構造器私有化 ? ? ? */ ? ? ?private Singleton() {} ?? ? ? ?/** ? ? ? * 創建本地變量實例 ? ? ? */ ? ? ?private final static Singleton instance = new Singleton(); ?? ? ? ?/** ? ? ? * 靜態方法用來返回實例 ? ? ? * @return ? ? ? */ ? ? ?public static Singleton getInstance() { ? ? ? ? ?return instance; ? ? } ?? ?? ?} ~~~ 優點: 1. 無多線程問題,隨著類的加載被加載 缺點: 1. 沒有達到懶加載的效果,如果一直沒有使用到這個實例,可能會導致內存的浪費。 如果確定該實例一定會被使用,則可以使用這個方式。 &nbsp; ## 餓漢式 - 靜態代碼塊 ~~~ ?package cn.net.smrobot.singleton.type2; ?? ?/** ? * 餓漢式 - 使用靜態代碼塊 ? */ ?public class Singleton { ?? ? ? ?public static void main(String[] args) { ?? ? ? } ?? ? ? ?/** ? ? ? * 私有化構造方法 ? ? ? */ ? ? ?private Singleton() {} ?? ? ? ?private static Singleton instance; ?? ? ? ?/** ? ? ? * 靜態代碼塊實例對象 ? ? ? */ ? ? ?static { ? ? ? ? ?instance = new Singleton(); ? ? } ?? ? ? ?public static Singleton getInstance() { ? ? ? ? ?return instance; ? ? } ?? ?} ~~~ 效果與靜態常量的方法是一樣的。 &nbsp; ## 懶漢式 - 線程不安全 ~~~ ?package cn.net.smrobot.singleton.type3; ?? ?/** ? * 懶漢式 ? * 線程不安全 ? */ ?public class Singleton { ? ? ?public static void main(String[] args) { ? ? ? ? ?Singleton instance = Singleton.getInstance(); ? ? ? ? ?Singleton instance1 = Singleton.getInstance(); ? ? ? ? ?System.out.println(instance == instance1); ? ? ? ? ?System.out.println("hashCode = " + instance.hashCode()); ? ? ? ? ?System.out.println("hashCode = " + instance1.hashCode()); ? ? } ?? ? ? ?private static Singleton instance; ?? ? ? ?private Singleton() {} ?? ? ? ?/** ? ? ? * 調用該方法的使用才去創建單例對象 ? ? ? */ ? ? ?public static Singleton getInstance() { ? ? ? ? ?if (instance == null) { ? ? ? ? ? ? ?instance = new Singleton(); ? ? ? ? } ? ? ? ? ?return instance; ? ? } ?? ?? ?} ~~~ 優點: 1. 可以起到懶加載的效果 缺點: 1. 在多線程的環境下,如果一個線程進入`if(instance == null)`語句判斷,但是還沒來得及執行`new instance()`,別的線程也進入了這個語句判斷,這樣可能會導致多個實例對象被創建,達不到單例的效果。 > 在實際開發中不要使用這種方式 &nbsp; ## 懶漢式 - 線程安全 ~~~ ?package cn.net.smrobot.singleton.type4; ?? ?/** ? * 懶漢式 ? * 線程安全 - 使用同步方法 ? */ ?public class Singleton { ? ? ?public static void main(String[] args) { ? ? ? ? ?Singleton instance = Singleton.getInstance(); ? ? ? ? ?Singleton instance1 = Singleton.getInstance(); ? ? ? ? ?System.out.println(instance == instance1); ? ? ? ? ?System.out.println("hashCode = " + instance.hashCode()); ? ? ? ? ?System.out.println("hashCode = " + instance1.hashCode()); ? ? } ?? ? ? ?private static Singleton instance; ?? ? ? ?private Singleton() {} ?? ? ? ?/** ? ? ? * 調用該方法的使用才去創建單例對象 ? ? ? * 加入同步處理代碼 ? ? ? * 解決線程安全問題 ? ? ? */ ? ? ?public static synchronized Singleton getInstance() { ? ? ? ? ?if (instance == null) { ? ? ? ? ? ? ?instance = new Singleton(); ? ? ? ? } ? ? ? ? ?return instance; ? ? } ?? ?? ?} ~~~ 這種方式使用`synchronized`同步的方式,但是在方法級別進行同步效率比較低,在實際開發中也不推薦使用。 &nbsp; ## 懶漢式 - 同步代碼塊 ~~~ ?package cn.net.smrobot.singleton.type5; ?? ?/** ? * 懶漢式 ? * 線程安全 - 使用同步代碼塊 ? */ ?public class Singleton { ? ? ?public static void main(String[] args) { ? ? ? ? ?Singleton instance = Singleton.getInstance(); ? ? ? ? ?Singleton instance1 = Singleton.getInstance(); ? ? ? ? ?System.out.println(instance == instance1); ? ? ? ? ?System.out.println("hashCode = " + instance.hashCode()); ? ? ? ? ?System.out.println("hashCode = " + instance1.hashCode()); ? ? } ?? ? ? ?private static Singleton instance; ?? ? ? ?private Singleton() {} ?? ? ? ?/** ? ? ? * 調用該方法的使用才去創建單例對象 ? ? ? * 加入同步處理代碼 ? ? ? * 解決線程安全問題 ? ? ? */ ? ? ?public static Singleton getInstance() { ? ? ? ? ?if (instance == null) { ? ? ? ? ? ? ?synchronized (Singleton.class) { ? ? ? ? ? ? ? ? ?instance = new Singleton(); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? ?return instance; ? ? } ?? ?? ?} ~~~ 仍然是線程不安全的,例如在進行if判斷時候有多個線程進入該分支,就會導致對象被同步的創建多次。 **不要使用** &nbsp; ## 雙重檢查 - Double Check 推薦使用,可以解決線程安全,懶加載,效率問題。 ~~~ ?package cn.net.smrobot.singleton.type6; ?? ?/** ? * 雙重檢查 ? */ ?public class Singleton { ? ? ?public static void main(String[] args) { ? ? ? ? ?Singleton instance = Singleton.getInstance(); ? ? ? ? ?Singleton instance1 = Singleton.getInstance(); ? ? ? ? ?System.out.println(instance == instance1); ? ? ? ? ?System.out.println("hashCode = " + instance.hashCode()); ? ? ? ? ?System.out.println("hashCode = " + instance1.hashCode()); ? ? } ?? ? ? ?/** ? ? ? * volatile 關鍵字很重要 ? ? ? */ ? ? ?private static volatile Singleton instance; ?? ? ? ?private Singleton() {} ?? ? ? ?/** ? ? ? * 調用該方法的使用才去創建單例對象 ? ? ? * 使用兩個if進行雙重檢查 ? ? ? */ ? ? ?public static Singleton getInstance() { ? ? ? ? ?if (instance == null) { ? ? ? ? ? ? ?synchronized (Singleton.class) { ? ? ? ? ? ? ? ? ?if (instance == null) { ? ? ? ? ? ? ? ? ? ? ?// 再進行一步判斷 ? ? ? ? ? ? ? ? ? ? ?instance = new Singleton(); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? ?return instance; ? ? } ?} ~~~ &nbsp; ## 靜態內部類 ~~~ ?package cn.net.smrobot.singleton.type7; ?? ?/** ? * 靜態內部類 ? */ ?public class Singleton { ? ? ?public static void main(String[] args) { ?? ? ? } ?? ? ? ?private Singleton() {} ?? ? ? ?/** ? ? ? * 只有調用getInstance方法時靜態內部類才會被加載 ? ? ? * 實例對象會被唯一創建一次 ? ? ? * 利用JVM底層機制類裝載的時候是線程安全的 ? ? ? */ ? ? ?private static class SingletonInstance { ? ? ? ? ?private final static Singleton INSTANCE = new Singleton(); ? ? } ?? ? ? ?public static Singleton getInstance() { ? ? ? ? ?return SingletonInstance.INSTANCE; ? ? } ?} ~~~ 可以達到線程安全和延遲加載的效果,線程安全是利用JVM的類裝載機制,JVM可以保證在加載一個類的時候是線程安全的,推薦使用。 &nbsp; ## 枚舉類型 ~~~ ?package cn.net.smrobot.singleton.type8; ?? ?/** ? * 枚舉模式 ? */ ?public enum Singleton { ?? ? ? ?INSTANCE; ? ? ? ?} ~~~ 由于其他單例模式的實質都是將構造方法私有化,但是通過反射是可以將構造方法設置為共有化的,于是就可以創建更多的對象了。而反射的代碼會判斷該類型是不是枚舉類型,如果是枚舉類型則會直接拋出異常。同時枚舉類型的序列化與反序列化可以保證對象一致。 可以避免多線程同步問題并且能夠防止反序列化重新創建新的對象,推薦使用。 > 參考:https://www.cnblogs.com/chiclee/p/9097772.html &nbsp; &nbsp; ## JDK中的源碼 RunTime &nbsp; ## 單例模式使用場景 1. 需要頻繁的進行創建和銷毀的對象。 2. 創建對象時耗時過多或者資源浪費過多。 3. 經常用到的對象,工具類對象,頻繁訪問數據庫或文件的對象(數據源,session工廠)。 4. Spring IOC容器的ApplicationContext用的是餓漢式的單例模式。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看