對於被voildate修飾過的變數大部分人都知道當乙個執行緒修改過後對另外乙個執行緒可見,具體是為什麼資料的講解比較少,通過讀併發程式設計的藝術對voildate變數的原理機制做下總結。
對於voildate變數來講是有兩個語義的,乙個是可見性問題,另外乙個是禁止指令重排。
1、可見性問題
相對於記憶體,cpu的速度是極高的,如果cpu需要訪問資料時都直接與記憶體打交道,在訪問過程中,cpu將一直空閒,這是一種極大的浪費,所以,現代的cpu裡都有很多暫存器,多級cache,他們比記憶體的訪問速度高多了。某個執行緒執行時,記憶體中的乙份資料,會存在於該執行緒的工作儲存中(working memory,是cache和暫存器的乙個抽象,每個執行緒都有自己的工作儲存),並在某個特定時候回寫到記憶體。單執行緒時,這沒有問題,如果是多執行緒要同時訪問同乙個變數呢?記憶體中乙個變數會存在於多個工作儲存中,執行緒1修改了變數a的值什麼時候對執行緒2可見?此外,編譯器或執行時為了效率可以在允許的時候對指令進行重排序,重排序後的執行順序就與**不一致了,這樣執行緒2讀取某個變數的時候執行緒1可能還沒有進行寫入操作呢,雖然**順序上寫操作是在前面的。這就是可見性問題的由來。
使用voildate變數,當寫的時候,jmm會把該執行緒對應的本地記憶體中的共享變數值重新整理到主記憶體中去,如果讀時,jmm會把該執行緒對應的本地記憶體置為無效,會直接從記憶體中去讀。
2、禁止重排序
加上voildate之後,voildate之後的變數不會排到前面去。
不管是可見性問題還是禁止指令重排,底層都是通過加lock的方式來構建的乙個記憶體屏障來做的
深入理解C語言 深入理解指標
關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...
mysql 索引深入理解 深入理解MySql的索引
為什麼索引能提高查詢速度 先從 mysql的基本儲存結構說起 mysql的基本儲存結構是頁 記錄都存在頁裡邊 各個資料頁可以組成乙個雙向鍊錶每個資料頁中的記錄又可以組成乙個單向鍊錶 每個資料頁都會為儲存在它裡邊兒的記錄生成乙個頁目錄,在通過主鍵查詢某條記錄的時候可以在頁目錄中使用二分法快速定位到對應...
深入理解C語言 深入理解指標
關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...