3 回答

TA貢獻(xiàn)2041條經(jīng)驗 獲得超4個贊
Java內(nèi)存模型定義了程序中所有動作的部分順序,這稱為巧合-before。
為了確保線程Y
能夠看到動作的副作用X
(X
無論是否發(fā)生在不同的線程中都無關(guān)緊要),在和之間定義了事前發(fā)生的關(guān)系。 如果不存在這種關(guān)系,則JVM可能會重新排序程序的操作。 現(xiàn)在,如果一個變量被多個線程共享和訪問,并且(至少)一個線程寫入了一個變量(如果讀寫未按關(guān)系發(fā)生前的順序進(jìn)行排序),那么您將進(jìn)行數(shù)據(jù)競爭。X
Y
在正確的程序中,沒有數(shù)據(jù)爭用。
示例是2個線程A
并B
在鎖上同步X
。Thread A
獲取鎖(現(xiàn)在Thread B
被鎖定)并執(zhí)行寫操作,然后釋放lock X
?,F(xiàn)在Thread B
獲取鎖X
和自所有的動作Thread A
都完成釋放之前鎖定X
,他們之前訂購的行動,Thread B
收購了鎖X
后線A
(也可見Thread B
)。
請注意,這發(fā)生在同一鎖上同步的操作上。還有就是沒有同步線程之間的關(guān)系之前發(fā)生在不同的鎖上

TA貢獻(xiàn)1805條經(jīng)驗 獲得超9個贊
本質(zhì)上是正確的。這樣做的主要目的是:除非您使用某種形式的同步,否則不能保證按照程序順序執(zhí)行寫操作后發(fā)生的讀操作將看到該寫操作的效果,因為語句可能已被重新定義。
在現(xiàn)實世界中是否存在這種情況(讀后見寫)?如果可以,您能給我一個真實的例子嗎?
從掛鐘的角度來看,很明顯,讀取看不到尚未發(fā)生的寫入的效果。
從程序順序的角度來看,由于如果沒有適當(dāng)?shù)耐剑P(guān)系之前發(fā)生),則可以對語句進(jìn)行重新排序,因此在程序?qū)懭胫斑M(jìn)行的讀取可能會在執(zhí)行期間看到該寫入的效果,因為它已被執(zhí)行由JVM寫入之后。
添加回答
舉報