JAVA高級開發-學習筆記(volatile關鍵字)

  1. 變量分爲哪幾類安全

    全局變量 = 屬性(靜態的、非靜態的) 局部變量 = 本地變量、參數bash

  2. 多線程間共享數據多線程

    全局變量:靜態變量或共享對象併發

  3. 併發線程能不能看到共享變量的最新值,這就是併發中變量可見性問題jvm

    (1) 爲何不可見?性能

    (2) 怎樣才能可見優化

    使用synchroized關鍵字,對線程主體進行包裝spa

    使用volatile關鍵字修飾共享變量線程

  4. JAVA內存模型及操做規範code

    (1) 共享變量必須存放在主內存。

    (2) 線程有本身的工做內存,線程只可操做本身的工做內存。

    (3) 線程要操做共享變量,需從主內存中讀取變量值到工做內存,改變後再從工做內存同步到主內存。

5. JAVA內存模型帶來的問題

(1) 數據存在多份拷貝,致使多線程同時讀寫同一變量時,存在數據不許確的問題。即線程安全問題。

(2) 因此要使用線程同步或鎖處理。

  1. 變量在線程1中更改,在線程2中能看到該變量的最新值

    (1) 線程1修改A後,必須立刻同步回主內存

    (2) 線程2使用A前,須要從新從主內存讀取到工做內存

  2. JAVA內存模型-同步交互協議,規定了8種原子操做

    (1) lock(鎖定) 將主內存中的變量鎖定,爲一個線程所獨佔。

    (2) unlock(解鎖) 將lock加的鎖解除,容許其它線程訪問主內存中的該變量。

    (3) read(讀取) 做用於主內存變量,將主內存中的變量值讀取到工做內存(從主內存讀取到寄存器)。

    (4) load(載入) 做用於工做內存變量,將read讀取到的值保存到工做內存中的變量副本中(寄存器變量載入到工做內存)。

    (5) use(使用) 做用於工做內存變量,將值傳遞給線程的代碼執行引擎。

    (6) assign(賦值) 做用於工做內存變量,將執行引擎處理返回的值從新賦值給變量副本。

    (7) store(存儲) 做用於工做內存變量,將變量副本的值傳送到主內存中(從工做內存讀取到寄存器)。

    (8) write(寫入) 做用於主內存變量,將store傳入的值寫入到主內存的共享變量中(寄存器變量寫入到主內存)。

    注意:任意間的組合操做,不是原子的。

    (1) 將一根變量從主內存複製到工做內存,要順序執行read、load操做;要將變量從工做內存同步回主內存要順序執行stroe、write操做。只要求順序執行,不必定是連續執行(即原子操做)。

    (2) 作了assign操做,必須同步回主內存。不能沒作assign操做,同步回主內存。(不必定assign後,立刻同步回主內存)

  3. 併發中保證變量可見性方法 final synchronized volatile

  4. synchronized語義規範(既能夠保證可見性,又能夠保證線程安全)

    (1) 進入同步塊前,先清空工做內存中的共享變量,從主內存中從新加載。

    (2) 解鎖前,必須把修改的共享變量同步回主內存。

    (3) 最核心的,是synchronized有鎖機制,只有得到鎖的線程才能操做共享資源。(悲觀鎖)

  1. volatile語義規範(保證可見性,保證工做內存的變量和主內存的變量的值一致)

    (1) 使用volatile變量時,必須從新從主內存加載,而且read、load是連續的。

    (2) 修改volatile變量後,必須立刻同步回主內存,而且store、write是連續的。

  2. volatile能作到線程安全嗎?(不能保證原子性)

    (1) 不能,由於它沒有鎖機制,線程可併發操做共享資源。

  1. volatile比synchronized,使用簡單、性能稍好。
  2. volatile還能夠用於限制局部代碼指令重排序

(1) 線程A和線程B的部分代碼

線程A
    content = initContent();
    
    isInit = true;
複製代碼
線程B
    while(isinit) {
        content.oper();
    }
複製代碼

(2) jvm優化指令重排序後

線程A(由於兩行代碼,沒有任何關係)
    isInit = true;
    content = initContent();
複製代碼

(3) 當兩個線程併發執行時,就可能出現線程B中content發生空異常。

  1. volatile的使用範圍

    (1) 只可修飾成員變量(靜態、非靜態)。由於用來保證共享變量可見性,共享變量只能是全局變量。

    (2) 多線程併發下,才須要使用。

  2. 單例模式中對volatile關鍵字的使用

相關文章
相關標籤/搜索