計算機執行程式時,每條指令都是在cpu中執行的,執行指令過程中,涉及到的資料的讀寫操作,程式執行過程中臨時資料都儲存在主存(物理記憶體)中,由於cpu的執行速度很快,所以資料的讀取和向記憶體中的的寫入相比較cpu的執行速度要慢很多,因此任何時候對資料的操作通過記憶體互動都會降低指令的執行速度,所以cpu裡面產生了快取記憶體。
對於多執行緒,在多核中,每條執行緒都執行於不同的cpu中,所以每個執行緒都有自己的快取記憶體;程式在執行時,將執行資料從主存中複製乙份到快取記憶體中,cpu在對資料進行計算時可以直接從快取記憶體中讀取資料和向其中寫入資料,當執行結束後,直接將結果寫入主存中。當乙個變數在多個cpu中都有快取時,則可能造成快取不一致問題。
解決快取不一致的2種方式:
(1)通過在匯流排加lock鎖;
因為在早期cpu與其他部件進行通訊是通過匯流排進行的,如果對匯流排進行lock鎖,則阻塞了其他cpu對其他部件的訪問,則只能有乙個cpu訪問這個變數的記憶體,
缺點:在匯流排加鎖期間,其他cpu無法訪問記憶體,導致效率低下。
(2)通過快取一致性協議;mesi協議中保證了每個快取中儲存的共享變數的副本都是一致性的。實質是:當cpu寫資料時,發現操作的變數是共享變數(其他cpu中也存在該變數),則通知其他cpu將該變數的快取行置為無效狀態,所以當其他變數讀取該變數時,發現該變數在快取中的快取行是無效狀態,所以直接去記憶體中重新讀取。
併發過程中的原子性、可見性、有序性
原子性:乙個操作或多個操作,要麼全部執行且執行過程中不被任何因素打斷,要麼不執行;
可見性:當多個執行緒訪問同乙個變數時,乙個執行緒修改了這個變數的值,則其他執行緒能夠看到修改後的值;
有序性:程式的執行順序按照**的執行順序;
指令重排序:處理器為了提高程式執行效率,對輸入**進行優化,則不保證程式中各個語句的執行順序同**中的執行順序一致,但是會保證**的最終執行結果與**順序的執行結果一致;所以處理器對**進行指令重排,但是會保證程式的最終結果和**順序執行結果順序一致,指令重排時,不能對有資料依賴性的語句進行重排,即指令重排語句前後對最終執行結果沒有影響,
注:指令重排不會影響單執行緒的執行,但是會影響多執行緒併發執行的正確性。
詳見:
volatile關鍵字解析
volatile 1.保證可見性 2.禁止重排序 我們先來看看乙個問題,關於i i 1的問題。首先,他不是乙個原子性的操作,我們通常將不可拆分的操作稱為原子操作 而i i 1需要先在主存中取得i的值,之後複製到快取記憶體之中,cpu再從快取記憶體中讀取並計算之後存入快取記憶體,最後把值再存入記憶體中...
Volatile關鍵字解析
volatile是j a虛擬機器提供的輕量級的同步機制 乞丐版 的synchronized 保證可見性 不保證原子性 禁止指令重排 可見性指當多個執行緒訪問同乙個變數時,如果其中乙個執行緒修改了這個變數的值,其他執行緒能夠立即看得到修改的值 驗證可見性demo import j a.util.con...
volatile關鍵字解析(一)
引起執行緒併發問題,可以簡單的總結為以下三條 原子性問題 什麼是原子性?原子性,即乙個操作或者多個操作,要麼全部執行並且執行過程中不會被任何因素打斷,要麼全部都不執行。如常見的銀行轉賬 count 操作等,都必須具備原子性才能保證不出現意外。a向b轉賬100元,需要保證兩步 a賬戶減100,b賬戶加...