1、要使volatile變數提供理想的執行緒安全,必須同時滿足以下兩個條件:
1)、對變數的寫操作不依賴於當前值;
2)、該變數沒有包含在具有其他變數的不變式中。
第乙個條件的限制使volatile變數不能用作執行緒安全的計數器。雖然增了操作(x++)看上去類似乙個單獨操作,實際上它是乙個由讀取-修改-寫入操作序列組成的組合操作,必須以原子方式執行,而volatile不能提供必須的原子特性。實現正確的操作需要使x的值在操作期間保持不變,而volatile變數無法實現這一點。
2、一般共享變數是存放中主記憶體中,每乙個執行緒都有乙個屬於自己的工作記憶體;當乙個執行緒開始時,會將變數從主記憶體中拷貝乙份副本放在自己的工作記憶體中,當使用時就高效多了,當有更改時,會回寫到主記憶體中;當此時有多個執行緒對同乙個共享變數進行操作時,只會操作屬於自己執行緒的工作記憶體,之後回寫到主記憶體中,相互之間不會有影響,故此時會有多執行緒安全問題。當該共享變數使用volatile修改時,乙個執行緒對其進行了修改,則其回寫到主記憶體時,會告知其他有該共享變數的副本,該副本已經失效了,故其他執行緒要使用該共享變數時,就會重新從主記憶體中拷貝乙份副本到本執行緒中,以確保其執行緒內使用的都是最新的。
3、一般乙個執行緒對變數的操作需要經歷從主記憶體中讀取read--->載入到工作執行緒中load---->在工作執行緒中使用use--->該該共享變數進行賦值asign--->對該共享變數進行儲存store--->將該共享變數回寫到主記憶體中write。
4、乙個共享變數被volatile修飾之後,就具備兩層含義:
1)、保證不同執行緒對這個變數進行操作時的可見性,即乙個執行緒修改了變數的值,該變數的新值對其他執行緒來說是立即可見的,但不保證操作的原子性;
2)、禁止進行指令重排。
5、使用synchronized可以保證變數修改的可見性和原子性,而volatile只能保證變數的可見性;synchronized是重量級的加鎖,且開銷大,而volatile是輕量級的無鎖,且開銷小
6、對於volatile修飾的引用型別(包括物件、陣列等),其僅僅是保證引用位址的可見性,而不是引用指向的物件中元素的可見性。
7、一般64位的long和double是非原子操作的,是使用高低32位來進行賦值的,故這種64位的變數的賦值是非原子操作的,但在現代jvm中,都已保證該賦值操作是原子操作的。
8、關於指令重排,是指處理器為了提高處理速度將一些指令重新排序,但保證最終的結果是一致的,跟重排前的結果一樣,這種是允許的;而volatile能防止指令重排,可以認為是在指令中增加了記憶體屏障,使在該volatile修飾的變數所屬的指令,在沒有使用之前,其前面的指令可以放在該指令之後,其後面的指令同樣可以放在該指令之前,但有了該修改,則不會這樣。
Linux預讀遲寫與sync
linux系統很重要的乙個效能提公升點就是它的pagecache,因為記憶體比io快太多了,所以大家都想進辦法來利用這個cache。檔案系統也不例外,為了達到高效能,檔案讀取通常採用預讀來 使用者的行為,把使用者可能需要的資料預先讀取到cache去,達到高效能的目的。當使用者儲存檔案時,linux核...
VUE的單向資料流與sync
子元件拿到父元件賦值的 attr 篩選出 props並儲存在子元件的 props裡 props中的資料逐一複製到子元件的例項上 同時設定get 和 set 當父元件data更新,渲染函式執行,又會執行上面的賦值。由此就達成了父元件的資料變化時,子元件props更新的效果。但是很明顯,當我們操作子元件...
vue中v model與 sync修飾符的使用差異
使用方式 子元件 示例 父元件 message children template import children from children.vue export default data watch script 子元件 h1 template export default props moun...