volatile 關鍵字 (二)

volatile 關鍵字 (二)

文章目錄

    • volatile 關鍵字 (二)
      • volatile 可以保證原子性么?

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

volatile 可以保證原子性么?

volatile 關鍵字能保證變量的可見性,但不能保證對變量的操作是原子性的。

我們通過下面的代碼即可證明:

/*** 微信搜 JavaGuide 回復"面試突擊"即可免費領取個人原創的 Java 面試手冊** @author Guide哥* @date 2022/08/03 13:40**/
public class VolatoleAtomicityDemo {public volatile static int inc = 0;public void increase() {inc++;}public static void main(String[] args) throws InterruptedException {ExecutorService threadPool = Executors.newFixedThreadPool(5);VolatoleAtomicityDemo volatoleAtomicityDemo = new VolatoleAtomicityDemo();for (int i = 0; i < 5; i++) {threadPool.execute(() -> {for (int j = 0; j < 500; j++) {volatoleAtomicityDemo.increase();}});}// 等待1.5秒,保證上面程序執行完成Thread.sleep(1500);System.out.println(inc);threadPool.shutdown();}
}

正常情況下,運行上面的代碼理應輸出 2500。但你真正運行了上面的代碼之后,你會發現每次輸出結果都小于 2500

為什么會出現這種情況呢?不是說好了,volatile 可以保證變量的可見性嘛!

也就是說,如果 volatile 能保證 inc++ 操作的原子性的話。每個線程中對 inc 變量自增完之后,其他線程可以立即看到修改后的值。5 個線程分別進行了 500 次操作,那么最終 inc 的值應該是 5*500=2500。

很多人會誤認為自增操作 inc++ 是原子性的,實際上,inc++ 其實是一個復合操作,包括三步:

  1. 讀取 inc 的值。
  2. 對 inc 加 1。
  3. 將 inc 的值寫回內存。

volatile 是無法保證這三個操作是具有原子性的,有可能導致下面這種情況出現:

  1. 線程 1 對 inc 進行讀取操作之后,還未對其進行修改。線程 2 又讀取了 inc的值并對其進行修改(+1),再將inc 的值寫回內存。
  2. 線程 2 操作完畢后,線程 1 對 inc的值進行修改(+1),再將inc 的值寫回內存。

這也就導致兩個線程分別對 inc 進行了一次自增操作后,inc 實際上只增加了 1。

其實,如果想要保證上面的代碼運行正確也非常簡單,利用 synchronizedLock或者AtomicInteger都可以。

使用 synchronized 改進:

public synchronized void increase() {inc++;
}

使用 AtomicInteger 改進:

public AtomicInteger inc = new AtomicInteger();public void increase() {inc.getAndIncrement();
}

使用 ReentrantLock 改進:

Lock lock = new ReentrantLock();
public void increase() {lock.lock();try {inc++;} finally {lock.unlock();}
}

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

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

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

相關文章

nextjs中_app.tsx下劃線什么作用

在Next.js中&#xff0c;_app.tsx&#xff08;或_app.js&#xff09;是一個特殊的文件&#xff0c;用于初始化頁面。下劃線_前綴在文件名中具有特定的意義&#xff0c;它告訴Next.js這個文件是一個特殊的內置文件&#xff0c;用于覆蓋或擴展默認的App行為。 具體來說&#xff…

Python 潮流周刊第 40 期(摘要)

本周刊由 Python貓 出品&#xff0c;精心篩選國內外的 250 信息源&#xff0c;為你挑選最值得分享的文章、教程、開源項目、軟件工具、播客和視頻、熱門話題等內容。愿景&#xff1a;幫助所有讀者精進 Python 技術&#xff0c;并增長職業和副業的收入。 周刊全文&#xff1a;h…

C++_數據結構_數據的輸入

作用 用于從鍵盤獲取數據 關鍵字 cin >> 變量示例

YOLOv5論文作圖教程(3)— 關于論文作圖教程系列采用線上培訓的通知(終結篇)

前言:Hello大家好,我是小哥談。YOLOv5論文作圖教程系列其實是我特別擅長的一個模塊(本人產品經理出身),自從本系列發表了兩篇文章之后,一直沒有再繼續更新,主要原因是通過文字無法比較好的表達軟件的功能及使用,并且也無法達到比較好的培訓效果。為了確保大家可以徹底掌…

數據庫原理(一)

1、基本概念 學號姓名性別出生年月籍貫220101張三男2003江蘇220102李四男2003山東220103王五女2003河北220104趙六女2003天津220105張四男2003北京220106李五女2003江蘇220107王六女2003山東220108張七男2003河北220109張九男2003天津220110李十女2003北京 1.1數據&#xff0…

基于springboot+vue的相親網站

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

軟考54-上午題-【數據庫】-關系模式的范式-真題

一、范式總結 第一步&#xff0c;先求候選碼&#xff0c;由此得到&#xff1a;主屬性、非主屬性。 二、判斷部分函數依賴的技巧 【回顧】&#xff1a;部分函數依賴 &#xff08;X&#xff0c;Y&#xff09;——>Z&#xff1b; X——>Z 或者 Y——>Z 題型&#xff1a;給…

全量知識系統問題及SmartChat給出的答復 之13 解析器+DDD+文法型 之2

Q36. 知識系統中設計的三種文法解析器和設計模式之間的關系 進一步&#xff0c;我想將 知識系統中設計的三種語言&#xff08;形式語言、人工語言和自然&#xff09;的文法解析器和DDD中的三種程序類型&#xff08;領域模型、領域實體和領域服務&#xff09; 形式語言文法 我…

Java中的圖數據庫應用:Neo4j入門

第1章&#xff1a;引言 在數據驅動的時代&#xff0c;咱們處理的不僅僅是數字和文本&#xff0c;還有復雜的關系和網絡。想象一下社交網絡中人與人之間錯綜復雜的聯系&#xff0c;或者是互聯網上網頁之間的鏈接關系&#xff0c;傳統的表格數據庫已經難以高效地處理這些關系密集…

每日leetcode--最大數

正題之前 三玖yyds&#xff01;&#xff01;&#xff01; 題目 給定一組非負整數 nums&#xff0c;重新排列每個數的順序&#xff08;每個數不可拆分&#xff09;使之組成一個最大的整數。 注意&#xff1a;輸出結果可能非常大&#xff0c;所以你需要返回一個字符串而不是整…

籃球游戲中的挑戰精神與慪氣心理:扣籃被帽后的再度沖擊

在籃球比賽中&#xff0c;扣籃無疑是最具觀賞性和震撼力的動作之一&#xff0c;它展示了球員的爆發力、技巧和自信。而在籃球游戲中&#xff0c;玩家即便面臨連續扣籃被蓋帽的挫折&#xff0c;仍渴望繼續殺入內線嘗試扣籃的現象&#xff0c;實則是體育競技精神、挑戰意識與慪氣…

梵寧教育:警惕網絡詐騙,守護青春未來

隨著互聯網的普及和科技的飛速發展&#xff0c;網絡已經深入到了我們生活的方方面面&#xff0c;為大學生提供了前所未有的便利與機遇。然而&#xff0c;與此同時&#xff0c;網絡詐騙也悄然滋生&#xff0c;成為威脅大學生安全的一大隱患。梵寧教育在此鄭重提醒廣大大學生&…

LeetCode 熱題100 刷題筆記

一&#xff1a;哈希表 一般哈希表都是用來快速判斷一個元素是否出現集合里。 直白來講其實數組就是一張哈希表&#xff0c;哈希表中關鍵碼就是數組的索引下標&#xff0c;然后通過下標直接訪問數組中的元素。 1.兩數之和 題目鏈接&#xff1a;. - 力扣&#xff08;LeetCode…

Javaweb之SpringBootWeb案例之自動配置的原理分析的詳細解析

3.2.3 原理分析 3.2.3.1 源碼跟蹤 前面我們講解了在項目當中引入第三方依賴之后&#xff0c;如何加載第三方依賴中定義好的bean對象以及配置類&#xff0c;從而完成自動配置操作。那下面我們通過源碼跟蹤的形式來剖析下SpringBoot底層到底是如何完成自動配置的。 源碼跟蹤技巧…

[VSCode插件] 輕量級靜態博客 - MDBlog

MDBlog VSCode插件&#xff0c;基于Markdown的輕量級靜態博客系統&#xff0c;同時支持導出為可以部署的靜態博客。 倉庫 MDBlog 1. Features 博客基礎功能&#xff1a;分類管理、文章管理、自動生成索引快捷指令&#xff1a;快捷輸入表格、mermaid、wavedrom、代碼塊發布&a…

[electron雜項] 記錄學習electron碰到問題(持續更新)

無法生成 node_modules文件夾 如前面所說的&#xff0c;如果要用vscode的代碼補全&#xff0c;那么就要把 electron.d.ts文件拷貝到項目的 node_modules文件夾下。一般情況下是通過npm install生成 node_modules 文件夾。但是有時發現根本生成不了生成了一個 xxxxlock的文件。…

Redis--內存回收機制詳解

什么是內存回收機制? 眾所周知Redis之所以性能高是因為數據都存在內存中&#xff0c;內存是很寶貴的&#xff0c;Redis的內存回收機制本質就是處理達到過期時間的key-value&#xff0c;以及當內存到達最大使用值時候觸發的內存淘汰策略。 Redis數據刪除的策略有哪些&#xf…

軟考重點題解析-基礎知識

1.加密技術&#xff1a;分為對稱加密技術&#xff1a;文件的加密和解密使用相同的密鑰 和 非對稱加密技術&#xff1a;加密和解密不同的密鑰&#xff0c;分別是公開密鑰和私有密鑰。 例題&#xff1a;若A,B兩人分別在認證機構&#xff08;CA&#xff09;M,N處獲得證書&…

項目準備March

Nginx主要用來作為Http服務器&#xff0c;要實現Tomcat的負載均衡&#xff0c;就可以通過Nginx來實現。 正向代理代理的是客戶端&#xff0c;反向代理代理的是服務端。SpringBoot采用約定優于配置的思想&#xff0c;簡化Spring項目的配置開發。 前端請求其實并未直接發送到后…

php連接hdfs初步探索

一、phdfs拓展 結果&#xff1a;暫時舍棄 安裝此拓展時&#xff0c;無法make成功&#xff0c;因為缺少hdfs.n文件。 換了其他版本的拓展包&#xff0c;并編譯都沒有找到此文件。 后搜到官網的相關資料&#xff0c;此hdfs.h的文件路徑的地址是$HADOOP_HDFS_HOME/include/hdfs…