Java併發-volatile和synchronized

volatile

功能

  1. 保證多線程的可見性
  2. 禁止一部分的重排序
  3. volatile 是輕量級的synchronized
  4. 對任意單個的volatile的讀/寫是原子性的(volatile=1/return volatile),但是複合型操作不支持。(volatile++操作)

特性

對於volatile來說具有以下特性
1.volatile標記的變量在讀操作的時候,一定是最新的值。
爲什麼?
1、lock前綴的支持,volatile規定每次修改操作必須刷新到內存,讀操作也要到內存中去取新值。
2、總線的支持,多條總線事務同一時刻同一時刻只有一條能獲得訪問內存的權限,因此,只要有線程修改了,那麼讀操作一定取到的是新值。
####內存語意
讀:當讀一個volatile變量時,JMM會把該線程對應的本地內存置爲無效。線程接下來將從主內存中讀取共享變
寫:當寫一個volatile變量時,JMM會把該線程對應的本地內存中的共享變量值刷新到主內

原理

instance = new Singleton(); // instance是volatile變量
0x01a3de1d: movb $0×0,0×1104800(%esi);0x01a3de24: **lock** addl $0×0,(%esp);

lock前綴的指令在多核處理器下會觸發兩種操作

  1. 將當前處理器緩存行的數據寫回到系統內存。
  2. 這個寫回內存的操作會使在其他CPU裏緩存了該內存地址的數據無效。

依賴CPU的緩存一致性的支持

volatile規則表

當第二個操作是volatile寫時,不管第一個操作是什麼,都不能重排序。這個規則確保volatile寫之前的操作不會被編譯器重排序到volatile寫之後。
當第一個操作是volatile讀時,不管第二個操作是什麼,都不能重排序。這個規則確保volatile讀之後的操作不會被編譯器重排序到volatile讀之前。
當第一個操作是volatile寫,第二個操作是volatile讀時,不能重排

在每個volatile寫操作的前面插入一個StoreStore屏障。
在每個volatile寫操作的後面插入一個StoreLoad屏障。
在每個volatile讀操作的後面插入一個LoadLoad屏障。
在每個volatile讀操作的後面插入一個LoadStore屏障。

synchronized

  1. 原子性。
  2. 由於線程同步,某一時刻,只能一個線程操作共享變量,也就保證了多線程間的可見性

使用

  • 普通同步方法:鎖是this鎖
  • 代碼塊:鎖是該對象鎖
  • 靜態同步方法:鎖是當前Class對象鎖

原理

  • 都是使用Monitor(監視器)對象來操作的
    monitorenter在編譯時插入到synchronized的開始位置,monitorexit在編譯時插入在synchronized的結束位置和者異常結束的位置。
  • 任何對象都是鎖對象,那麼任何對象都與一個monitor相關聯,當獲取到monitor,該monitor就會處於鎖定狀態。當指令執行到monitorenter時,就會去嘗試獲取該monitor的所有權。

原子性

  • 通過鎖來實現一些列操作的原子性。但是性能差,會造成阻塞,增加性能消耗。
  • 通過CAS(compare and swap)來實現,此實現針對於賦值操作。i++,
    • 通過E(期望值,也就是緩存/本地內存/工作內存的副本),V(當前值)來操作。通過E和主內存的值進行比較,如果相等的話,就會將新值賦值給當前值。
    • 問題,會造成ABA的問題,當其他線程將共享變量的值變換爲B,然後再該爲A,那麼該線程去將本地內存的值刷到主內存的時候,將會執行成功。但是結果可能是錯的。
  • 通過CAS+version的方式來解決ABA的問題。
    • 也就是,共享變量V的值爲 1A->2B->3A 那麼通過此版本號去控制,就不會巧妙的去除ABA問題。
  • 注意,CAS只能處處理一個變量,如果多個可以使用ij = 1a的方式,AtomicReference保證引用對象的原子性。
  • CAS 不需要添加鎖,但是循環驗證會增加CPU的消耗。

核心代碼

  • CAS實現操作,CASXXXX方法就是CAS操作。Unsafe.class 操作c代碼。
    do{
        N = E+1;
    }while(CASXXXX((E,N));

java concurrent包下的atomic類

AtomicInteger  AtomicBoolean...(CAS,會出現BAB的問題)
AtomicStampedReference 解決了CAS的ABA的問題
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章