下面的代碼可以在多線程中工作嗎? !boolean是java中的一個原子操作嗎?!!boolean是java中的一個原子操作嗎?
volatile boolean flag = true;
if (!flag){
do something
}
下面的代碼可以在多線程中工作嗎? !boolean是java中的一個原子操作嗎?!!boolean是java中的一個原子操作嗎?
volatile boolean flag = true;
if (!flag){
do something
}
是
!boolean
在java中的一個[n]原子操作嗎?
號有三個操作位置:
線程切換可以發生在1和2之間,或者2和3之間,並且底層布爾值的值可以在任何時間或者在3或之後改變。
所以如果你想確定'做點什麼'只發生如果flag
是同時錯誤,你將不得不同步,或使用信號量。
因爲它標誌着volatile
和值是一種原始的,這樣保證了讀取將始終是一致(不讀部分初始化值的可能性)。
即使沒有標記爲volatile
,JVM也會始終以原子方式讀取存儲在32位或更小中的任何原始值。這是JLS 17.6中的語言要求。 (JLS 17.7允許對64位原始值進行「字符撕裂」,即long
和double
,它說這種行爲是特定於實現的。實際上,在我所知的所有生產64位JVM實現中,甚至可以讀取64位值始終是原子的。)
反轉布爾操作的操作可能不是原子讀取,但如果是這樣的話,它將通過將布爾值複製到JVM指令堆棧工作,所以仍然不存在數據的可能性腐敗(因爲將值推入操作數棧是一個原子操作)。更有可能的是,JIT只會將您的if
條件反轉並跳轉到另一個分支,而不是實際反轉布爾值。
當然,你仍然沒有任何保證,在它被另一個線程改變之前,它不會立即讀取該值,所以從字面上看,下一個指令可以開始執行,同時布爾值被另一個線程設置爲true線。
即使是這樣,一旦你進入if體內什麼阻止它再次改變值呢?這與「not」期間的變化有何不同?爲什麼你的代碼依賴於這是原子? – GManNickG
這是一個原子讀取(無論是否爲volatile),但「做某事」與前面的檢查無關,除非您同步它。 – shmosel
爲什麼不使用AtomicBoolean對象? –