java記憶體模型及volatile關鍵字

大資料最好發表於2019-01-16

一、基本概念

在併發程式設計過程中,我們經常會遇到三類問題:原子性問題,可見性問題,有序性問題。下面我們來介紹一下和這些問題相關的三個概念。
1.原子性
也就是執行一個操作,要不全部執行成功,要不執行失敗。比如a=0,這個操作就是原子性的,要麼賦值成功,要麼賦值失敗。再比如a++操作,這個操作就不是原子性的,它是三步操作的組合:a)獲取a的值。b)執行a=a+1操作。c)寫入新的a的值
2.可見性
就是說再一個執行緒中執行對改變了一個變數,在另一個執行緒中依然能看到這個變數改變後的值,我們可以使用volatile來保證執行緒之間變數的可見性。
3.有序性
在java記憶體模型中,為了提高效能,允許JVM對程式碼執行重排序,這種操作在單執行緒中不會有問題,但是會影響多執行緒程式的正確性。而volatile和synchronized關鍵字以及Lock都可以保證程式的有序性。

二、java記憶體模型

在java多執行緒程式執行時,各個執行緒都會先從主存中獲取變數,然後在執行過程中對變數進行計算時,都是和自己執行緒中的變數進行互動,不同執行緒之間的變數彼此不可見。因此導致多個執行緒之間的變數不可見。
在這裡插入圖片描述

三、volatile關鍵字

一個被volatile關鍵字修飾的變數,會有兩層語義。
  1)保證了不同執行緒對這個變數進行操作時的可見性,即一個執行緒修改了某個變數的值,這新值對其他執行緒來說是立即可見的。
  2)禁止進行指令重排序。
一個被volatile修飾的變數,在每次被使用到時,會強制從主存中去獲取,當計算完成,會強制將變數寫入主存,這樣就保證了執行緒間變數互相可見。
volatile關鍵字只會保證可見性和有序性,而不能保證原子性,而synchronized關鍵字既可以保證原子性,又可以保證可見性,又可以保證有序性。

相關文章