国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

java 單例模式容易忽略的細節

瀏覽:2日期:2022-08-19 10:04:57
java單例模式

直接講實現單例模式的兩種方法:懶漢式和餓漢式,單例模式的概念自己上網搜吧這里就不講了!

這里會涉及到java中的jvm,如果你沒有這方面的知識,我建議你先去補補,不然會有點迷糊!

首先說說類什么時候進行加載?

java虛擬機沒有進行強制性的約束,但是對于初始化卻嚴格規定了有且只有4種情況必須先對類進行初始化。

我們要知道的是在類加載的過程中,加載、驗證、準備是在初始化之前完成的,所以進行了初始化,加載、驗證、準備自然就在之前完成了。

然后這四種情況是分別遇到 new 、 getstatic 、 putstatic 和 invokestatic 這四條指令時,如果對應的類沒有初始化,則要對對應的類先進行初始化。

講完類加載時機,就可以講懶漢式和餓漢式了。

直接先說說懶漢式為什么是線程不安全的?

先看最開始的代碼:

public class Student2 { //1:構造私有 private Student2(){} //2:定義私有靜態成員變量,先不初始化 private static Student2 student = null; //3:定義公開靜態方法,獲取本身對象 public static Student2 getSingletonInstance(){ //沒有對象,再去創建 if (student == null) { student = new Student2(); } //有對象就返回已有對象 return student; } }

結合之前講的類加載內容,遇到new或加載靜態方法了就會進行類加載了。

線程1它new了一個對象,線程2它緊接著也new一個對象,第二個對象的值把第一個對象的值覆蓋了,不管new了多少個對象,都會產生垃圾對象,只有最后一個對象才會保持住,其他對象都會變成不可達對象,被垃圾回收,這個過程就相當于產生了大量無效對象,這就是線程不安全的原因!

那為了讓懶漢式變得線程安全,我們要怎么做?

看代碼:

public class Student4 { private volatile static Student4 student = null; private Student4() {} public static Student4 getSingletonInstance() { if (student == null) {//第一個null判斷,是先大范圍過濾一遍 synchronized (Student4.class) {if (student == null) { student = new Student4();} } } return student; }}

這個叫雙重檢查鎖DCL,第一個if先大范圍判斷是不是空值,經過synchronized,線程1先進去執行完后,線程2才能進去,然后第二個if判斷是否完成創建類的實例,線程1創建完了,線程2就不用創建了。

那為什么要加volatile關鍵字呢?

因為我們Student student = new Student()的執行過程是:

1、new觸發類加載機制(已經被加載過的類不需要再次加載)

2、分配內存空間

3、將對象進行初始化4、講對象引用地址賦值給棧空間中的變量但我們JVM中的JIT即時編輯器會對代碼的執行過程進行優化,把過程變為1、2、4、3。

這是什么意思呢?就是未經初始化直接賦值,這樣就是student直接有值了,但整個對象還未初始化完成,所以這個對象是不完整的,是個未成品。在JVM規范中,它是一個根本不能用的對象。

到了這個時候,線程1做了這么多事,我們讓它休息會,給CPU稍微停一下,線程2就來了,它就直接得到了對象,但它調用對象的方法時,就會報錯。雖然這個對象有值,但還未初始化完成。所以我們要加上volatile關鍵字禁止指令重新排序。

面試重災區說的差不多了,餓漢式還是要講講。

最后就說說餓漢式為什么沒有線程安全問題?​

看代碼:

public class Student1 { // 2:成員變量初始化本身對象 private static Student1 student = new Student1(); // 構造私有 private Student1() { } // 3:對外提供公共方法獲取對象 public static Student1 getSingletonInstance() { return student; } public void sayHello(String name) { System.out.println('hello,' + name); }}

根據類加載的東西,在多線程的條件下,線程1先執行getSingletonInstance()時,就會進行類加載,類的靜態資源就會進行初始化。根據JVM安全機制里說的,當一個類被JVM加載的時候,該類的加載是線程安全的,相當于JVM對該過程加鎖了。所以整個過程處于一個鎖的范圍內,然后靜態成員變量進行初始化就相當于Student1()被new了,只會被new一次。

當第二個線程進來,它就發現這個類已經被加載了,就不需要進行加載了,對象也不需要頻繁創建,所以線程是安全的!

總結

老劉看過很多關于java單例模式的資料,多多少少都會缺少一點細節,這次老劉把它補全了。

最后,如果覺得有哪里寫的不好或者有錯誤的地方,可以聯系公眾號:努力的老劉,進行交流。

如果覺得寫的不錯,給老劉點個贊!

以上就是java 單例模式容易忽略的細節的詳細內容,更多關于java 單例模式的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
主站蜘蛛池模板: 米奇精品一区二区三区 | 国产精品线在线精品国语 | 亚洲黄色小视频 | 美女被靠视频免费网站不需要会员 | 亚洲经典在线 | a一级 | 岛国大片在线播放高清 | 日韩三级在线 | 亚洲精品区在线播放一区二区 | 成人在线免费视频播放 | 免费久久精品 | 精品国产亚洲一区二区三区 | 久久99精品热在线观看15 | 免费一级做a爰片性色毛片 免费一极毛片 | 欧美亚洲国产成人综合在线 | 欧美精品束缚一区二区三区 | 成人精品一区二区三区中文字幕 | 亚洲国产成人综合精品2020 | 亚洲久久网| 欧美色成人综合 | 性欧美一级毛片 | 久久久久国产成人精品 | 成人自拍视频 | 欧美一级毛片香蕉网 | 欧美成在线播放 | 国产成人免费永久播放视频平台 | 欧美日韩一区二区中文字幕视频 | 国产三级精品在线观看 | 国产主播福利精品一区二区 | 国产毛片一区二区三区精品 | 99久久国语露脸精品对白 | 国产三级理论 | 国产高清天干天天视频 | 在线视频一二三区 | 国产精品成人一区二区 | 日韩在线视精品在亚洲 | 国产亚洲精品一区二区在线播放 | 亚洲精彩视频在线观看 | 精品香蕉99久久久久网站 | 日韩欧一级毛片在线播无遮挡 | 日本成人免费在线观看 |