日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java—关于单例模式的实现方式

發布時間:2023/12/18 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java—关于单例模式的实现方式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.餓漢式(線程安全,調用效率高,但是不能延時加載):JVM初始化的時候創建對象,不能延時

public class Singleton { private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; } }

2.懶漢式(線程安全,調用效率不高,但是能延時加載):

public class Singleton {//類初始化時,不初始化這個對象(延時加載,真正用的時候再創建)private static Singleton instance;private Singleton(){}public static synchronized Singleton getInstance(){if(instance==null){instance=new Singleton();}return instance;} }

3.靜態內部類實現方式(線程安全,調用效率高,可以延時加載):

public class Singleton {private Singleton() {}private static class SingletonHolder{private static final Singleton singleton = new Singleton();}public static Singleton getInstance(){return SingletonHolder.singleton;}}

如果多個線程同時去初始化一個類,那么只會有一個線程去執行這個類的類構造器,其他線程都需要阻塞等待,直到活動線程執行方法完畢。

特別需要注意的是,在這種情形下,其他線程雖然會被阻塞,但如果執行方法的那條線程退出后,其他線程在喚醒之后不會再次進入/執行方法,因為在同一個類加載器下,一個類型只會被初始化一次。如果在一個類的方法中有耗時很長的操作,就可能造成多個線程阻塞,在實際應用中這種阻塞往往是隱藏的。

4.枚舉類(線程安全,調用效率高,不能延時加載,可以天然的防止反射和反序列化調用):

枚舉就是在一個類里定義幾個靜態變量,每個變量都是這個類的實例。

public enum Singleton {//枚舉元素本身就是單例INSTANCE;//添加自己需要的操作public void singletonOperation(){} }

5.雙重檢查鎖 DCL

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

鎖之前判斷是為了優化,提高性能。鎖是為了防止多線程同時申請到多個實例。

但是卻有一個致命的缺陷,那就是初始化對象并不是一個原子操作,

instance = new Singleton();

為了提高性能,編譯器和處理器常常會對指令進行重排序。重排序分為三種:編譯器重排序,指令級并行重排序,內存系統重排序,實現優化,優化結果可能是

  • 初始化 Singleton?對象;  
  • 把 Singleton?對象地址賦給instance變量;
  • 也可能是這樣

  • 初始化一半Singleton?對象;
  • 把Singleton?對象地址賦給instance變量;
  • 初始化剩下的Singleton?對象;
  • 如果是第二種情況,在多線程情況下第一個線程已經進入了instance = new Singleton?(); 正在初始化,此時已經將Singleton?對象的地址賦給instance變量,但是Singleton?對象仍為初始化完畢。導致對象的某些屬性為空的情況。

    解決方法:instance變量加上,重排序限制,也就是volatile。

    總結

    以上是生活随笔為你收集整理的Java—关于单例模式的实现方式的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。