volatile 關鍵字 (一)

volatile 關鍵字 (一)

文章目錄

    • volatile 關鍵字 (一)
      • 如何保證變量的可見性?
      • 如何禁止指令重排序?

文章來自Java Guide 用于學習如有侵權,立即刪除

如何保證變量的可見性?

在 Java 中,volatile 關鍵字可以保證變量的可見性,如果我們將變量聲明為 volatile ,這就指示 JVM,這個變量是共享且不穩定的,每次使用它都到主存中進行讀取。

JMM(Java 內存模型)

JMM(Java 內存模型)強制在主存中進行讀取

volatile 關鍵字其實并非是 Java 語言特有的,在 C 語言里也有,它最原始的意義就是禁用 CPU 緩存。如果我們將一個變量使用 volatile 修飾,這就指示 編譯器,這個變量是共享且不穩定的,每次使用它都到主存中進行讀取。

volatile 關鍵字能保證數據的可見性,但不能保證數據的原子性。synchronized 關鍵字兩者都能保證。

如何禁止指令重排序?

在 Java 中,volatile 關鍵字除了可以保證變量的可見性,還有一個重要的作用就是防止 JVM 的指令重排序。 如果我們將變量聲明為 volatile ,在對這個變量進行讀寫操作的時候,會通過插入特定的 內存屏障 的方式來禁止指令重排序。

在 Java 中,Unsafe 類提供了三個開箱即用的內存屏障相關的方法,屏蔽了操作系統底層的差異:

public native void loadFence();
public native void storeFence();
public native void fullFence();

理論上來說,你通過這個三個方法也可以實現和volatile禁止重排序一樣的效果,只是會麻煩一些。

下面我以一個常見的面試題為例講解一下 volatile 關鍵字禁止指令重排序的效果。

面試中面試官經常會說:“單例模式了解嗎?來給我手寫一下!給我解釋一下雙重檢驗鎖方式實現單例模式的原理唄!”

雙重校驗鎖實現對象單例(線程安全)

public class Singleton {private volatile static Singleton uniqueInstance;private Singleton() {}public  static Singleton getUniqueInstance() {//先判斷對象是否已經實例過,沒有實例化過才進入加鎖代碼if (uniqueInstance == null) {//類對象加鎖synchronized (Singleton.class) {if (uniqueInstance == null) {uniqueInstance = new Singleton();}}}return uniqueInstance;}
}

uniqueInstance 采用 volatile 關鍵字修飾也是很有必要的, uniqueInstance = new Singleton(); 這段代碼其實是分為三步執行:

  1. uniqueInstance 分配內存空間
  2. 初始化 uniqueInstance
  3. uniqueInstance 指向分配的內存地址

但是由于 JVM 具有指令重排的特性,執行順序有可能變成 1->3->2。指令重排在單線程環境下不會出現問題,但是在多線程環境下會導致一個線程獲得還沒有初始化的實例。例如,線程 T1 執行了 1 和 3,此時 T2 調用 getUniqueInstance() 后發現 uniqueInstance 不為空,因此返回 uniqueInstance,但此時 uniqueInstance 還未被初始化。

大家好,我是xwhking,一名技術愛好者,目前正在全力學習 Java,前端也會一點,如果你有任何疑問請你評論,或者可以加我QQ(2837468248)說明來意!希望能夠與你共同進步

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/716395.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/716395.shtml
英文地址,請注明出處:http://en.pswp.cn/news/716395.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Linux安裝軟件命令及vim、gcc使用說明】

安裝軟件命令 Linux安裝軟件的命令首先要進入管理員權限 首先在終端輸入sudo su切換到管理員界面 輸入對應的密碼,注意這里的密碼不會顯示出來,輸完密碼之后回車即可。當出現root就代表已經是管理員界面了。 如果相應退出管理員界面輸入exit即可。 注…

django-paramiko遠程服務器和文件管理(五)

一、paramiko簡介 1.paramiko是一個基于SSHv2協議的純Python庫。需要單獨安裝。 2.它提供了客戶端和服務器的功能。 3.可以實現SSH2遠程安全連接,支持用戶名、密碼連接,也支持密鑰連接 4.一般用于執行遠程命令、傳輸文件、中間SSH代理等 安裝 pip3 in…

數組、冒泡排序、函數、作用域、對象、Math

數組 1.定義數組: a)通過字面量的方式定義數組 let ary[1,2,3,4]b)通過定義構造函數的方式定義數組: let 數組名new Array(值,值,值);數組的操作方式 a)增 //在數組末尾添加值 arr.push(新增的內容) //在數組的開始添加值 arr.unshift(新增的內容)b…

Redis主從復制+Redis哨兵模式+Redis群集模式

Redis主從復制Redis哨兵模式Redis群集模式一、Redis主從復制1、主從復制的作用2、主從復制過程3、搭建Redis主從復制3.1 所有節點服務器安裝redis3.2 修改Redis配置文件(Master節點操作)3.3 修改Redis配置文件(Slave節點操作)3.4 驗證主從效果 二、Redis哨兵模式1、哨兵模式的作…

8、IBOScms代碼審計

一、sql注入 1、sql注入(Ⅰ) 限制 rreport/api/getlist {"offset":0,"type":"send","keyword":{"subject":"111) AND (updatexml(1,concat(0x7e,(select user()),0x7e),1))-- qw"}}復現 POST /?rreport/api/…

Vue開發實例(十一)用戶列表的實現與操作

用戶列表的實現與操作 一、創建用戶頁面和路由二、表格優化1、表頭自定義2、表格滾動3、加入數據索引4、利用插槽自定義顯示 三、功能1、查詢功能3、增加4、刪除5、修改 一、創建用戶頁面和路由 創建用戶頁面 在 src/components/Main 下創建文件夾user,創建文件Us…

Java ZooKeeper-RocketMQ 面試題

Java ZooKeeper-RocketMQ 面試題 前言1、談談你對ZooKeeper的理解 ?2、Zookeeper的工作原理(Zab協議)3、談談你對分布式鎖的理解,以及分布式鎖的實現?4、 zookeeper 是如何保證事務的順序一致性的?5、 zook…

設計模式之策略模式詳解

目錄 什么是策略模式 應用場景 業務場景實現 抽象類 實現類 Context上下文 測試類 策略模式的優缺點 什么是策略模式 他將定義的算法家族、分別封裝起來,讓他們之間可以相互替換,從而讓算法的變化不會影響到使用算法的用戶。 策略模式使用的就是…

idea出現莫名其妙錯的時候

正常情況idea使用起來都很順手,但是當項目比較多的時候,可能出現莫名奇妙的錯誤,比如導入的包始終報錯java: 程序包com不存在,或者引入自己寫的包也不存在,或者始終出現紅線但是排查之后沒有問題的情況,這種…

進來吧,給自己10分鐘,這篇文章帶你直接學會python

Python的語言特性 Python是一門具有強類型(即變量類型是強制要求的)、動態性、隱式類型(不需要做變量聲明)、大小寫敏感(var和VAR代表了不同的變量)以及面向對象(一切皆為對象)等特點的編程語言。 獲取幫助 你可以很容易的通過Python解釋器獲取幫助。如果你想知道一個對象(o…

OJ:鏈表的中間結點

876. 鏈表的中間結點 - 力扣(LeetCode) 思路 思路:首先最容易想到的思路是什么呢,就是先遍歷一遍鏈表,用一個值count來記錄鏈表的長度,然后我們運用除法,/2,結果是幾,就…

【C++干貨基地】揭秘C++11常用特性:內聯函數 | 范圍for | auto自動識別 | nullptr指針空值

🎬 鴿芷咕:個人主頁 🔥 個人專欄: 《C干貨基地》《粉絲福利》 ??生活的理想,就是為了理想的生活! 引入 哈嘍各位鐵汁們好啊,我是博主鴿芷咕《C干貨基地》是由我的襄陽家鄉零食基地有感而發,不知道各位的…

平臺工程: 用Backstage構建開發者門戶 - 2

本文介紹了如何使用開源Backstage構建自己的開發者門戶,并基于此實踐平臺工程。本系列共兩篇文章,這是第二篇。原文: Platform Engineering: Building Your Developer Portal with Backstage — Part 2 在本教程第一部分中我們了解了Backstage這個用于構…

外貿網站模板建站

測繪檢測wordpress外貿主題 簡潔實用的wordpress外貿主題,適合做測繪檢測儀器設備的外貿公司使用。 https://www.jianzhanpress.com/?p5337 白馬非馬衣服WordPress外貿建站模板 白馬非馬服裝行業wordpress外貿建站模板,適用于時間服裝企業的官方網站…

Git 如何上傳本地的所有分支

Git 如何上傳本地的所有分支 比如一個本地 git 倉庫里定義了兩個遠程分支,一個名為 origin, 一個名為 web 現在本地有一些分支是 web 遠程倉庫沒有的分支,如何將本地所有分支都推送到 web 這個遠程倉庫上呢 git push web --all

pytorch loss函數整理

變量名解釋 logits:未經過normalize(未經過激活函數處理)的原始分數,例如一個mlp將特征映射到num_target_class維的輸出tensor就是logits。 probs:probabilities的簡寫,logits經過sigmoid函數,…

Doris實戰——銀聯商務實時數倉構建

目錄 前言 一、應用場景 二、OLAP選型 三、實時數倉構建 四、實時數倉體系的建設與實踐 4.1 數倉分層的合理規劃 4.2 分桶分區策略的合理設置 4.3 多源數據遷移方案 4.4 全量與增量數據的同步 4.5 離線數據加工任務遷移 五、金融級數倉穩定性最佳實踐 5.1 多租戶資…

Jenkins的Pipeline概念

文章目錄 Pipeline什么是Jenkins Pipeline聲明式和腳本式Pipeline語法為何使用PipelinePipeline概念PipelineNodeStageStep Pipeline語法概述聲明式Pipeline腳本式Pipeline Pipeline示例 參考 Pipeline 什么是Jenkins Pipeline Jenkins Pipeline是一套插件,它支持…

【Django】model模型—模型繼承

Django中三種繼承風格 抽象基類:僅將父類用于子類公共信息的載體,這樣的父類永遠都不會單獨使用。多表繼承:繼承了一個模型(可能來源其它應用),且想要每個模型都有對應的數據表。代理模型:只想…

JProfiler相關問題及答案(2024)

1、JProfiler是什么及其用途 JProfiler是一款功能豐富的商業Java性能剖析(profiling)工具,它主要面向開發者和性能分析師,用于監測和分析Java應用程序的運行時行為。以下是對JProfiler的一些詳細介紹和它的主要用途: …