為什麼要理解volatile關鍵字,才能夠明白線程操作的意義?

2020-12-17 願編程是詩

為什麼說理解volatile關鍵字,才能理解線程操作的意義?對於初學者來說,volatile只是簡單的了解,只知道volatile作用就是「保證可見性」、「禁止指令重排序」,但是仍然存在一些誤區。

對於volatile關鍵字,可以說是Java虛擬機提供的最輕量級的同步機制,但是它「不能保證原子性」,所以很多程式設計師都習慣去避免使用它,遇到需要處理多線程數據競爭問題的時候一律使用 synchronized來進行同步。今天就花點時間聊一聊volatile關鍵字。

大家都是知道volatile是保證線程可見性的,所謂的可見性就是當一條線程修改了這個變量的值,然後新的值對其他所有線程都可以立即知道,這樣就是保證了線程安全。

但是對於volatile關鍵字,尤其在初學者開發時經常被誤解,認為「volatile變量對所有線程是立即可見性的,對volatile變量所有的寫操作都能立刻反映到其他線程之中。也就是說volatile變量在各個線程中是一致的,所以基於volatile變量的運算在並發下是線程安全的」,這句話論據部分並沒有錯。但是請看下一段:

雖然論據部分並沒有錯,但是由其論據並不能得出「基於volatile變量的運算在並發下是線程安全的」這樣的結論。我們可以從物理存儲的角度去分析,當各個線程的工作內存中volatile變量也可以存在不一致的情況,但由於每次使用之前都要先刷新到主內存,執行引擎看不到不一致的情況,因此可以認為不存在一致性問題。在Java運算操作符並非原子操作,這導致volatile變量的運算在並發下一樣是不安全的。

因此在使用volatile變量時,我們要知道它在運用運算場景中如何去使用,很多時候我們仍然要通過加鎖來保證原子性的。所以使用volatile需要滿足以下兩點:

變量不需要與其他的狀態變量共同參與不變約束運算結果並不依賴變量的當前值或確保只有單一的線程修改變量的值即可使用volatile變量還有一個作用就是「禁止指令重排序」。(指令重排序會干擾程序的並發執行)

白嫖不易,記得點個讚!

需要【Java複習腦圖、電子書】關注我,且私信「資料」集合獲取。

相關焦點

  • 你應該要理解的java並發關鍵字volatile
    提高java的並發編程,就不得不提volatile關鍵字,不管是在面試還是實際開發中 volatile都是一個應該掌握的技能。他的重要性不言而喻。因此也有必要學好。一、為什麼要用到volatile關鍵字?
  • 知名公司面試題:談談你對volatile關鍵字的理解
    作為一名java程式設計師,求職面試時,關於volatile關鍵字時常會遇到。張工最近到某知名網際網路公司面試,面試官提出這樣的一個問題:談談你對volatile關鍵字的理解張工一時間沒有回答上來,面試官:你都工作三年了,怎麼對volatile關鍵字都沒掌握啊。
  • C語言丨深入理解volatile關鍵字
    來源:小職(z_zhizuobiao)找我:✅ 解鎖高薪工作 ✅ 免費獲取乾貨教程在C語言中,還有一個並不常用但卻非常有用的關鍵字volatile。許多程式設計師無法正確的理解C語言關鍵字volatile。這並不奇怪,大多數C原因書籍不過一兩句一帶而過。本文將告訴你如何正確使用它。
  • 如何理解volatile關鍵字
    面試中常常會問道,說說你對volatile的理解?在講解之前,我們先來了解一個Java並發編程中可見性的問題。這個工作內存類似於一個高速的本地緩存,線程在代碼的執行過程中,可以直接從自己本地緩存裡加載變量副本,不需要要從主內存加載變量值,性能會得到極大的提升。
  • 什麼時候需要使用volatile關鍵字
    想必大家平時都見過volatile關鍵字,可是大家知道什麼時候需要使用volatile關鍵字嗎?volatile int a = 100;volatile關鍵字和const關鍵字相對應,const關鍵字告訴編譯器其修飾的變量是只讀的,編譯器根據只讀屬性做一些操作,而volatile關鍵字告訴編譯器其修飾的變量是易變的,同理編譯器根據易變屬性也會做一些操作。它會確保修飾的變量每次都讀操作都從內存裡讀取,每次寫操作都將值寫到內存裡。
  • Java內存模型與volatile關鍵字
    Java的內存模型大概樣子還是有必要了解下的,今天就學習了下,順便學習了一點volatile關鍵字!每個線程獲取這類變量都是先把變量從主內存加載到工作內存,然後才能進行使用,同樣如果是修改,那麼也是先修改了工作內存中的變量,然後再從工作內存同步進主內存中。
  • 分享牛人解釋的volatile關鍵字
    一個指針可以是volatile 嗎?解釋為什麼。3).一般說來,volatile用在如下的幾個地方:1、中斷服務程序中修改的供其它程序檢測的變量需要加volatile;2、多任務環境下各任務間共享的標誌應該加volatile;3、存儲器映射的硬體寄存器通常也要加volatile說明,因為每次對它的讀寫都可能由不同意義;另外,以上這幾種情況經常還要同時考慮數據的完整性(相互關聯的幾個標誌讀了一半被打斷了重寫),在1
  • 可惜了,面試敗在了volatile關鍵字上,直擊痛點搞懂volatile
    當然,想要適應社會的進步,程式設計師也要不斷的給自己充電,但人能忘本,基礎知識還是要學紮實的。這不,有位同學就來找我訴苦了,前兩次面試都挺順利的,到了三面竟然栽在了volatile關鍵字上。volatile 的作用是作為指令關鍵字,確保本條指令不會因編譯器的優化而省略volatile 的特性保證了不同線程對這個變量進行操作時的可見性,即一個線程修改了某個變量的值,這新值對其他線程來說是立即可見的。
  • volatile關鍵字詳解
    的三個特點保證線程之間的可見性禁止指令重排不保證原子性可見性概念可見性是多線程場景中才討論的,它表示多線程環境中,當一個線程修改了共享變量的值,其他線程能夠知道這個修改。>如上述代碼,如果不加volatile,程序運行結果如下加上volatile關鍵字後,程序運行結果如下
  • Java並發之volatile關鍵字內存可見性問題
    Java並發之volatile關鍵字內存可見性問題線程之間數據共享案例我們先來看一個場景:Main函數啟動後,調用一個線程向list中添加數據。這是為什麼呢?那麼這個時候,在Java中怎麼實現線程之間共享數據的內存可見性呢?這裡就是我們今天需要講解的關鍵字:volatile。
  • 深度解析volatile關鍵字,就是這麼簡單
    .dylib關鍵字volatile是Java虛擬機提供的最輕量級的同步機制,當一個變量被關鍵字volatile修飾之後,它有如下兩個特性:保證了這個變量對所有線程的可見性禁止指令重排序優化關鍵字volatile可以保證變量對所有線程的可見性,也就是當一個線程修改了這個變量的值,其他線程能夠立即得到修改的值。
  • Java並發編程徹底搞懂volatile關鍵字
    本篇文章主要對volatile關鍵字進行解剖。解決辦法是使用volatile關鍵字。關鍵字volatile的作用是強制從公共堆棧中取得變量的值,而不是從線程私有數據棧中取得變量值。說明:在多線程環境中,use和assign是多次出現的,但這一操作並不是原子性,也就是read和load之後,如果主內存count變量發生修改之後,線程工作內存中的值由於已經加載,不會產生對應的變化,也就是私有內存和公共內存中的變量不同步,所以計算時結果和預期不一致,也就出現線程安全問題。
  • Java 多線程 —— 深入理解 volatile 的原理以及應用
    推薦閱讀:《java 多線程—線程怎麼來的》這一篇主要講解一下volatile的原理以及應用,想必看完這一篇之後,你會對volatile的應用原理以及使用邊界會有更深刻的認知。本篇主要內容:volatile 讀寫同步原理volatile重排序原則volatile應用關鍵字volatile是jvm提供的輕量級的同步機制,但它並不容易理解,而且在多數情況下用不到,被多數開發者拋棄並採用synchronized代替,synchronized屬於重度鎖,如果你對性能有高的要求,那麼同等情況下,變量聲明volatile會減小更少的同步開銷
  • 從零開始了解多線程知識之開始篇目——jvm&volatile
    在多處理器系統上,內核可以分派屬於同一進程的多個線程在多個處理器上運行,提高進程執行的並行度。由於需要內核完成線程的創建、調度和管理,所以和用戶級線程相比這些操作要慢得多,但是仍然比進程的創建和管理操作要快。大多數市場上的作業系統,如Windows,Linux等都支持內核級線程。
  • 從底層原理深度剖析volatile關鍵字,徹底徵服面試官
    閱讀本文之前,推薦大家先閱讀作者之前的一篇關於happens-before的文章,這樣更有助於大家對volatile關鍵字底層原理的理解。這裡必然會存在時間差,在這個時間差內,該線程對副本的操作,對於其他線程是不見的,從而造成了可見性問題。
  • 面試官最愛的 volatile 關鍵字,這些問題你都搞懂了沒?
    可見性即用volatile關鍵字修飾的成員變量表明該變量不存在工作線程的副本,線程每次直接都從主內存中讀取,每次讀取的都是最新的值,這也就保證了變量對其他線程的可見性。另外,使用volatile還能確保變量不能被重排序,保證了有序性。
  • 1分鐘讀懂java中的volatile關鍵字
    本文將以儘量簡潔的方式介紹java中的volatile關鍵字。如果覺得寫的不錯,記得,如果寫的不好歡迎批評指正,讓我們一起進步!volatile作為java中的關鍵詞之一,用以聲明變量的值可能隨時會別的線程修改,使用volatile修飾的變量會強制將修改的值立即寫入主存,主存中值的更新會使緩存中的值失效(非volatile變量不具備這樣的特性,非volatile變量的值會被緩存,線程A更新了這個值,線程B讀取這個變量的值時可能讀到的並不是是線程A更新後的值)。
  • Java中volatile關鍵字概覽
    一、第一章 volatile關鍵字概覽多線程下變量的不可見性概述在多線程並發執行下,多個線程修改共享的成員變量,會出現一個線程修改了共享變量的值後,另一個線程不能直接 看到該線程修改後的變量的最新值。不包含局部變量,因為局部變量 是線程私有的,因此不存在競爭問題。每一個線程還存在自己的工作內存,線程的工作內存,保留了被線程使用的變量的工作副本。 線程對變量的所有的操作(讀,取)都必須在工作內存中完成,而不能直接讀寫主內存中的變量。
  • Java中 volatile 關鍵字的最全總結,趕快給自己查缺補漏吧!
    (1)互斥即一次只允許一個線程持有某個特定的鎖,一次就只有一個線程能夠使用該共享數據。(2)可見性要更加複雜一些,它必須確保釋放鎖之前對共享數據做出的更改對於隨後獲得該鎖的另一個線程是可見的。也即當一條線程修改了共享變量的值,新值對於其他線程來說是可以立即得知的。
  • 教學筆記:這樣來學習Java volatile關鍵字
    相信大多數Java程式設計師都學習過volatile這個關鍵字的用法。百度百科上對volatile的定義:volatile是一個類型修飾符(type specifier),被設計用來修飾被不同線程訪問和修改的變量。volatile的作用是作為指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值。