1. 程式人生 > >對於long和double型變數的特殊規則及原子性,可見性和有序性

對於long和double型變數的特殊規則及原子性,可見性和有序性

Java記憶體模型要求lock,unlock,read,load,assign,use,store,write這8個操作都具有原子性,但對於64位的資料型別(long或double),在模型中定義了 一條相對寬鬆的規定,允許虛擬機器將沒有被volatile修飾的64位資料的讀寫操作劃分為兩次32位的操作來進行,即允許虛擬機器實現選擇可以不保證64位資料型別的load,store,read,write這4個操作的原子性,即long和double的非原子性協定。

ps:一般情況下不需要把用到的long和double變數專門宣告為volatile

原子性:

  • 由Java記憶體模型來直接保證的原子性變數操作包括read,load,assign,use,store,write,我們可以大致認為基本資料型別
    的訪問讀寫是具備原子性的
  • 在synchronized塊之間的操作也具有原子性

可見性:

可見性是指當一個執行緒修改了共享變數的值,其他執行緒能夠立即得知這個修改

可見性的實現:Java記憶體模型是通過變數修改後將新值同步回主記憶體,在變數讀取前從主記憶體重新整理變數值,將主記憶體作為傳遞媒介

volatile的特殊規則保證了新值能立即同步回主記憶體,以及每次使用前立即從主記憶體中重新整理

還有能夠實現可見性的關鍵字:synchronized和final

  • 同步程式碼塊的可見性是由“對一個變數執行unlock操作之前,必須先把此變數同步回主記憶體中”
  • final的可見性是指:被final修飾的欄位在構造器中一旦初始化完成,並且構造器沒有吧“this”的引用傳遞出去,那在其他執行緒中就能看見final的值

有序性:

如果在本執行緒內觀察,所有操作都是有序的,如果在一個執行緒中觀察另一個執行緒,所有操作都是無序的:首先“執行緒內表現為序列語義”;其次“指令重排序”和“工作記憶體和主記憶體同步延遲”

Java語言提供了volatile和synchronized兩個關鍵字來保證執行緒之間操作的有序性

synchronized關鍵字具備以上三種特性