探究Java如何實現原子操作(atomic operation)


1. 讓我們首先了解下java 中 Volatile 關鍵字

     Volatile可實現java內存模型當中的可見性,

     java內存模型的可見性:

可見性,是指線程之間的可見性,一個線程修改的狀態對另一個線程是可見的。也就是一個線程修改的結果,另一個線程馬上就能看到。

比如:用volatile修飾的變量,就會具有可見性。volatile修飾的變量不允許線程內部緩存和重排序,即直接修改內存。所以對其他線程是可見的。

                                                   BUT

Volatile 不保證原子性:

 just like this:

  volatile int a=0; a 具有可見性 但是如下操作仍然不具有原子性 a++;

讓我們看看什么是原子操作 什么是非原子操作:

原子操作:a=0;

非原子操作 a++,即a=a+1;

那么在java 中 如何保證原子性呢?方法是 sync ,lock,unlock


2 .那么volatile的實現原理是什么?

    先這樣理解:

     把對volatile變量的單個讀/寫,看成是使用同一個鎖對這些單個讀/寫操作     做了同步。示例:

             

 
示例程序

下面的程序等價於上面的示例程序

 

 
等價程序

volatile的特性:

  (1) 對一個volatile變量的單個讀/寫操作,與對一個普通變量的讀/寫操作使用同一個鎖來同步,它們之間的執行效果相同。

可見性:對一個volatile變量的讀,總是能看到(任意線程)對這個volatile變量最后的寫入。

原子性:對任意單個volatile變量的讀/寫具有原子性,但類似於volatile++這種復合操作不具有原子性。


3:來談談-------鎖

      3.1:釋放鎖和獲取鎖的內存語義

  當線程釋放鎖時,JMM會把該線程對應的本地內存中的共享變量刷新到主內存中,示例代碼如下:

 

 
code

假設線程A執行writer()方法,隨后線程B執行reader()方法。

整個的執行過程如下:threadA(1->2->3)->threadB(4->5->6)

根據happen-before原則:3執行前的所有A線程的操作在3執行成功后對4以后的流程立即可見

鎖釋放和鎖獲取的內存意義:當線程釋放鎖時,JMM會把該線程對應的本地內存中的變量刷新到主內存中。

當線程獲取共享變量時,會把本地內存中的變量設置為無效,

從而使得被監控的臨界區中的代碼必須去主內存中去讀取共享變量。


4:那就來看看 atomic operation,原子操作不需要sync:



作者:銅雀春深鎖不住
鏈接:https://www.jianshu.com/p/5195f7f742a8
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM