juc 並發包的基礎 cas 與 volatile

2021-08-18 14:11:47 字數 1751 閱讀 9198

即一種對記憶體中的資料進行操作的指令,而且該操作是原子的操作其過程如下:首先cpu將記憶體中的將要被修改的資料與預期的值進行比較,如果這兩個值相等,cpu則會將記憶體中數值替換為新值,否則不做操作。使用非阻塞演算法,定義乙個執行緒的失敗或者掛起,是不會影響其它執行緒的失敗或者掛起的。該操作是直接修改記憶體中的值,所以可以認為該操作是原子操作。但 cas 存在 aba 問題,假設存在 t1,t2 兩個執行緒,t1 執行緒在記憶體中對引數 v 進行操作,先把引數 v 的值從 a 變為 b,t2 這是對引數 v 進行 cas 操作是不成功的,因為此時引數 v 的值為 b,然後執行緒 t1 又把引數 v 從 b 修改為 a ,這時 t2 又可以對引數 v 進行 cas 操作,此時又是成功的,但此時的成功不意味著沒有問題,因為引數 v 在 t2 對其進行 cas 操作時其值並不一直都是 a。

volatile實現了多執行緒的有序性和可見性,但是並不具備原子性,

-有序性:因為 cpu 執行的速度是非常高效的,為了防止乙個耗時很長的指令在「執行」階段呆很長時間,而導致後續的指令都卡在「執行」之前的階段上。處理器在不改變執行結果的情況下可以改變指令的執行順序。指令重排序對單執行緒沒有什麼影響,他不會影響程式的執行結果,但是會影響多執行緒的正確性。編譯器重排序,編譯器在不改變單執行緒程式語義的前提下,可以重新安排語句的執行順序;處理器重排序,如果不存在資料依賴性,處理器可以改變語句對應機器指令的執行順序;但是對於被。對於 volatile 禁止指令重排序,是對被 volatile 修飾的變數彙編成的**新增記憶體屏障(實質上是一組指令)進行處理器對其進行重排序,即是按照指令的排序順序執行。

-原子性:volatile 修飾的變數並不具體原子性特徵。因為在記憶體底層對變數的修改是分三步操作完成的,例如 i++;要修改 i 的值,第一步執行緒會先到主存上把 i 的值讀取到本地,第二步對 i 進行加 1 操作,第三步把 i 的值提交到主存上,如果是單執行緒環境下這是沒問題的,但如果是多執行緒併發場景下,比如有 t1 和 t2 兩個執行緒要對 i 的值進行修改,t1 執行緒需要對 i 進行加 1 操作,而 t2 執行緒需要對 i 進行加 2 操作,t1 , t2 把主存上 i 的值都讀取到本地, t1 對 i 進行修改後在 t1 快取記憶體中 i 的值為 i+1 , t2 對 i 進行修改後在 t2 快取記憶體中 i 的值為 i+2 ,這時 t1 執行緒先把 i 的值提交到主存中,主存中 i 的值為 i+1 ,然後 t2 再把修改後 i 的值提交到主存中,這時主存中 i 的值就會變成 i+2,對於 t1 快取記憶體中 i 的值就會變成乙個髒資料,並不安全的。

-可見性:對於 volatile 修飾的變數,會加入記憶體讀屏障和記憶體寫屏障,寫屏障的作用是,某個執行緒對被 volatile 修飾的變數做修改時,會讓這個變數的修改後的值即刻同步到主存上;讀屏障的作用是當乙個執行緒對被 volatile 修飾的變數進行修改時,會通過執行緒間的通訊讓其它執行緒快取記憶體中對應的變數的值失效,強制讓其執行緒重新去主存上面讀取該變數最新的值,即當乙個執行緒對被 volatile 修飾的變數做修改的時候,其它執行緒都能獲取到最新的值,也就是乙個執行緒對 volatile 修飾的變數做修改,其它執行緒是可見的。

-總結:如果乙個變數被 volatile 修飾時,如果再對這個變數的修改操作是 cas 操作,那麼這個變數就具備了有序性,可見性和原子性,那麼對於這個變數的修改在多執行緒併發場景下就是安全的。 juc 並發包的基礎就是volatile 和 cas ,而 atomic 類就是對 volatile 和 cas 聯合使用最基本的操作。例如:乙個執行緒對於 atomicinteger 類的例項變數的修改操作,對其它執行緒都是可見的,而且是安全的。

J U C並發包梳理與補充

併發工具類 tools 執行緒執行器 executor 鎖 locks 在不同的地方學習了許多和併發相關的工具或者類並總結在了不同的博文中,這裡做乙個總的關係梳理並進行相關的補充,首先來看下 j.u.c 包下的分類 主要分為如下幾個部分 執行緒執行器 executor 及其執行緒池實現類 鎖 loc...

併發程式設計cas的aba問題

多執行緒環境下,兩個執行緒a,b可能會對共享資料m進行操作。為了保證乙個執行緒在讀到資料跟寫入資料之間沒有被其他執行緒修改過,使用cas解決。cas 更改之前先判斷舊值是否有變化,如果沒有變化,認為沒有執行緒對該共享值做過操作。這種認為是有一下問題的,時執行緒a 執行緒bt1 讀m值為1 t2讀m值...

cas的基礎配置

去除https的j基礎認證方式 cas的 deployerconfigcontext.xml spring configuration ticketgrantingticketcookiegenerator.xml spring configuration warncookiegenerator.x...