java單例模式中雙重檢查鎖定的volatile的作用解析
volatile對singleton的建立過程的重要性:
- 禁止指令重排序(有序性)
例項化一個物件其實可以分為三個步驟:
(1)分配記憶體空間。
(2)初始化物件。
(3)將記憶體空間的地址賦值給對應的引用。
但是由於作業系統可以對指令進行重排序,所以上面的過程也可能會變成如下過程:
(1)分配記憶體空間。
(2)將記憶體空間的地址賦值給對應的引用。
(3)初始化物件
如果是這個流程,多執行緒環境下就可能將一個未初始化的物件引用暴露出來,從而導致不可預料的結果(如題目的描述,這裡就是因為 instance = new Singleton(); 不是原子操作,編譯器存在指令重排,從而存線上程1 建立例項後(初始化未完成),執行緒2 判斷物件不為空後對其操作,但實際物件仍為空,造成錯誤)。因此,為了防止這個過程的重排序,我們需要將變數設定為volatile型別的變數,volatile的禁止重排序保證了操作的有序性。
- Singleton物件的記憶體可見性
這裡由於synchronized鎖的是Singleton.class物件,而不是Singleton物件,所以synchronized只能保證Singleton.class物件的記憶體可見性,但並不能保證Singleton物件的記憶體可見性;這裡用volatile宣告Singleton,可以保證Singleton物件的記憶體可見性。這一點作用也是非常重要的(如題目的描述,避免因為執行緒1 建立例項後還只存在自己執行緒的工作記憶體,未更新到主存。執行緒 2 判斷物件為空,建立例項,從而存在多例項錯誤)。
相關推薦
java單例模式中雙重檢查鎖定的volatile的作用解析
volatile對singleton的建立過程的重要性:禁止指令重排序(有序性)例項化一個物件其實可以分為三個步驟: (1)分配記憶體空間。 (2)初始化物件。 (3)將記憶體空間的地址賦值給對應的引用。但是由於作業系統可以對指令進行重排序,所以上面的過程也可能會變成如下過程: (1)分配記憶體空間。
Java單例模式中雙重檢查鎖的問題
單例建立模式是一個通用的程式設計習語。和多執行緒一起使用時,必需使用某種型別的同步。在努力建立更有效的程式碼時,Java 程式設計師們建立了雙重檢查鎖定習語,將其和單例建立模式一起使用,從而限制同步程式碼量。然而,由於一些不太常見的 Java 記憶體模型細節的原因,並不能
java單例模式(雙重檢查加鎖)的原因
csharp sta get 第一次 instance new 同步機制 原因 AR public class Singleton{ private static Singleton instance = null;//是否是final的不重要,因為最多只可能實
Java單例模式(雙重檢查)
今天又想起了單例模式,看了網上好多文章,加鎖和可見性。自己也寫了一遍單例模式。 public class SingleTon { private SingleTon(){ } private static volatile SingleTon singleTon=null
Java 單例模式中使用雙重檢查(Double-Check)
在 Effecitve Java 一書的第 48 條中提到了雙重檢查模式,並指出這種模式在 Java 中通常並不適用。該模式的結構如下所示: public Resource getResource() { if (resource == null)
(GOF23設計模式)_單例模式_雙重檢查鎖式_靜態內部類式_列舉式
設計模式 a、建立型模式 單例模式、工廠模式、抽象工廠模式、建造者模式、原型模式 b、結構型模式 介面卡模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式 c、行為型模式 模板方法模式、命令模式、迭代器模式、觀察者模式、中介
Java單例模式中的飽漢式和飢漢式
Java中單例模式是筆試的常見題目,包括飽漢式和飢漢式,具體程式碼實現如下:飽漢式:public class SingleTon { private SingleTon(){} priv
java單例模式中餓漢式與懶漢式區別
餓漢式: 設計思想:構造方法私有,這樣就保證了在外部是無法例項化物件的;然後先在內部定義一個靜態常量物件,再寫一個static方法來返回這個物件,這樣就保證是一個物件了。 【程式碼實現】 public class HungryManSingleton { /**
單例模式中的雙重檢查加鎖
本文是在學習單例模式時遇到的問題 在多執行緒中,如何防止單例模式被多次例項,當然是要加鎖啦。但是加了鎖就意味著執行緒雖然安全,但效率肯定會變低,這是,就出現了雙重檢查加鎖。但看到這段程式碼,我又有疑問了? public class Singleton { private vo
java單例模式優缺點(懶漢模式,餓漢模式,雙重檢查加鎖模式)
三種單例模式實際都是有運用的。 優點:延遲載入 缺點:不加同步的懶漢式是執行緒不安全的,加了synchronized之後就變成執行緒安全的了 public class Singleton { private static Singleton singleto
單例模式中 的 雙重檢查鎖 概念與用法
它的 lock acc env syn 可見 cost ola check public class Singleton { //私有的 靜態的 本類屬性 private volatile static Singleton _instance;
Java基礎 Runtime 用了單例模式中的餓漢式
face ring lang run ice ffi new es2017 obj 禮悟: 好好學習多思考,尊師重道存感恩。葉見尋根三返一,活水清源藏於零。 虛懷若谷良心主,皓月當空自在王。願給最苦行無悔,誠勸且行且珍惜。
java單例模式雙重檢驗鎖的優缺點?還有哪些實現方式?列舉一些使用場景
2018年7月18日,在專案程式碼中看到單例模式,總結一下單例模式的知識點. 單例模式的概念: 在應用程式的生命週期中,在任意時刻,引用某個類的例項都是同一個.在一個系統中有些類只需要有一個全域性物件,統一管理系統行為和執行某些操作.例如在使用hibernate時,ses
【Java 單例模式】Java 單例模式在多執行緒環境中可能存在的問題
在多執行緒環境下,使用延遲載入的方式實現單例模式,會出現錯誤。 例如,使用如下方式實現單例類: package study20170307; /** * Created by apple on 17/3/7. */ public class Sin
java 單例模式及在SSH框架中運用
定義: 確保某一個類只有一個例項,而且自動例項化並向整個系統提供這個例項。 程式碼: Singleton類稱為單例類,通過使用private的建構函式確保了在一個應用中只產生一個例項,並且是自行例項化的。 Java程式碼 /** * 執行緒安全的
Java面試題之在多線程情況下,單例模式中懶漢和餓漢會有什麽問題呢?
餓漢模式 問題 之間 static 代碼 clas ava public 餓漢 懶漢模式和餓漢模式: public class Demo { //private static Single single = new Single();//餓漢模式
從一個小例子引發的Java記憶體可見性的簡單思考和猜想以及DCL單例模式中的volatile的核心作用
環境 OS Win10 CPU 4核8執行緒 IDE IntelliJ IDEA 2019.3 JDK 1.8 -server模式 場景 最初的程式碼 一個執行緒A根據flag的值執行死迴圈,另一個執行緒B只執行一行程式碼,修改flag的值,讓A執行緒死迴圈終止。 Vis
Java單例模式
class auth pre light java on() ack private gets package singleton; /** * 單例模式 * @author pengYi * */ public class Singleton { priva
你所不知道的單例模式和多線程並發在單例模式中的影響
影響 編程問題 rop key 是我 提升 註意 特性 是不是 單例對象(Singleton)是一種常用的設計模式。在Java應用中,單例對象能保證在一個JVM中,該對象只有一個實例存在。這樣的模式有幾個好處: 1、某些類創建比較頻繁,對於一些大型的對象,這是一筆很大的系
java單例模式等一些程序的寫法....持續更新...
new tor zed bsp 更新 餓漢式 blog stat cto 一、單例模式的寫法: public class MyFactory { /** * 餓漢式 */ private static MyFactory instanc