1. 程式人生 > >java單例模式中雙重檢查鎖定的volatile的作用解析

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