✨你瞭解volatile,但你知道它在單例模式中的作用嗎?
小知識,大挑戰!本文正在參與“程式設計師必備小知識”創作活動
Code皮皮蝦 一個沙雕而又有趣的憨憨少年,和大多數小夥伴們一樣喜歡聽歌、遊戲,當然除此之外還有寫作的興趣,emm...,日子還很長,讓我們一起加油努力叭🌈
✨作用
以 雙重檢查單例模式為例,先上程式碼
```java public class Singleton {
public Singleton() {
}
private static volatile Singleton singleton;
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
} ```
如上述程式碼所示,singleton 用了 volatile 修飾,而我們都知道 volatile 的作用
- 不能保證原子性
- 保證共享變數的可見性
- 禁止指令重排序
那麼在單例模式中,volatile的作用到底是什麼呢?
其實,在單例模式中,volatile的作用主要是 禁止指令重排序
那麼為什麼呢?
在上述程式碼中,singleton = new Singleton(); 可分解為以下步驟:
- 分配物件記憶體空間
- 初始化物件
- 設定 singleton 指向分配的記憶體地址
但是步驟2,3是可能交換的,也就是發生重排序,但是根據 Java語言規範 intra-thread semantics,它是允許那些在單執行緒內,不會改變單執行緒程式執行結果的重排序,也就是說,雖然步驟2,3發生重排序,但是對於單執行緒來說,初次訪問物件時,其結果都是正確的,所以即使重排序也無所謂了。
但是在多執行緒環境中,這就會出現問題,例如,如下多執行緒發生重排序案例:
| 時間 | 執行緒A | 執行緒B | | ---- | --------------------------------- | -------------------------------------------------------- | | t1 | 分配物件空間 | | | t2 | 設定 singleton 指向分配的記憶體空間 | | | t3 | | 判斷 singleton 是否為空 | | t4 | | 由於 singleton 不為null,執行緒B將訪問singleton 引用的物件 | | t5 | 初始化物件 | | | t6 | 訪問 singleton 引用的物件 | |
有上述表格流程可以看出,在發生重排序的情況下,會導致執行緒B在 t3 時間下,判斷出 singleton 不為null,那麼執行緒B就會拿到這個 singleton 去做別的事,那麼此時這個 singleton 沒有初始化,那麼就會報錯,這就出了問題。
正常流程而言,在t2時間執行緒A應該對 singleton初始化,那麼執行緒B在
可能會有小夥伴就差臨門一腳的感覺就懂了,那我根據程式碼再說一遍
```java public class Singleton {
public Singleton() {
}
private static volatile Singleton singleton;
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
} ```
根據程式碼而言,如果執行緒A在 第12行 即 singleton = new Singleton();發生重排序,那麼執行緒B在 第9行即第一個if (singleton == null)處就有可能判斷出 singleton不為null,進而拿到返回的 singleton 去做別的事進而導致報錯。
講到這裡相信各位小夥伴差不多都懂了,如果還不懂可以多看兩遍。
所以為了解決這個問題,就使用 volatile來修飾 singleton,來禁止重排序而可能出現的問題。
😉精選專欄
毛遂自薦,給大家推薦一下自己的專欄😁,歡迎小夥伴們收藏關注😊
❤最後
我是 Code皮皮蝦,一個熱愛分享知識的 皮皮蝦愛好者,未來的日子裡會不斷更新出對大家有益的博文,期待大家的關注!!!
創作不易,如果這篇博文對各位有幫助,希望各位小夥伴可以==一鍵三連哦!==,感謝支援,我們下次再見~~~
- Mysql查詢詳解(條件查詢、子查詢、模糊查詢、連線查詢。。。)
- 【美團技術沙龍】海量文章分類爬取,零基礎教學附文件原始碼,就問還有誰???
- ✨Python必備知識點:從零帶你學習正則表示式
- Python高階:【百度翻譯逆向】圖文影片教學!!!
- Python爬蟲利器之Beautiful Soup入門詳解,實戰總結!!!
- Python爬蟲網頁解析神器Xpath快速入門教學!!!
- 【小白快速入門小程式爬蟲】從零寫起:高清桌布小程式爬蟲!!!
- 【微信小程式爬蟲】表情包小程式圖文影片教學,從零寫起,保姆教程!!!
- 貢獻!程式設計師大學四年珍藏的26個寶藏網站,全部拿出來了!!!
- 花式玩轉二叉樹遍歷,遞迴迭代應有盡有,絕對滿足您的需求!!!
- 帶你掌握被大廠面試官狂轟亂炸的ThreadLocal原理,別再傻乎乎的說不了解了~~~
- ✨你瞭解volatile,但你知道它在單例模式中的作用嗎?