假設有3個執行緒,
執行緒 1 和 2 將原子地增加或減少全域變數 X。
執行緒 1:
atomic_increase(X)
執行緒 2:
atomic_decrease(X)
執行緒 3 將檢查 X 是否大于某個預定義值并相應地執行操作。
執行緒 3:
if( X > 5 ) {... logic 1 ...}
else {... logic 2 ....}
我認為這些atomic_xxx操作還不夠。它們只能同步執行緒 1 和 2 之間的修改。
如果X通過螺紋1或2改變線3后結束所述比較和進入 logic 1。
我必須用一個互斥體的所有3個執行緒同步時修改或讀的X?
添加 1
順便說一句,邏輯 1 和邏輯 2 不修改 X。
uj5u.com熱心網友回復:
總之是的,讀取也需要以某種方式同步,否則讀取不一致的風險是真實的。在讀取和寫入之間執行的讀取atomic_increase將不一致。
但是,如果logic 1或對logic 2執行某些操作X,您的問題似乎并不止于此。我認為那么您需要事務的概念,它以讀取(X > 5事物)開始,然后以寫入(logic 1或logic 2)結束。
uj5u.com熱心網友回復:
答案取決于您的應用程式的用途。如果邏輯 1 和邏輯 2 都沒有修改X,則很可能不需要額外的同步(除了使用 atomic_load 讀取X)。
我假設您將內在函式用于原子操作,而不僅僅是互斥鎖(或 Java 中的同步塊)中的增量。例如,在 Java 中有一個AtomicInteger類具有諸如“incrementAndGet”和“get”之類的方法。如果您使用它們,則可能不需要額外的同步,但這取決于您實際想要使用邏輯 1 還是邏輯 2 實作的目標。
例如,如果您想在 時顯示一條訊息X > 5,那么您可以這樣做。到訊息顯示時, 的值X可能已經更改,但事實仍然是,訊息是由X大于 5 至少在一段時間內觸發的。
換句話說,如果沒有額外的同步,你只能保證在X大于 5 時呼叫邏輯 1 ,但不能保證在執行邏輯 1 期間它會保持不變。對你來說可能沒問題,也可能沒問題.
uj5u.com熱心網友回復:
是的,答案是happens before鏈接,讓我們說Thread-1開始執行atomic_increase方法。它將持有lock并進入synchronized要更新的塊X。
private void atomic_increase() {
synchronized (lock) {
X = X 1; // <-- Thread-1 entered synchronized block, yet to update variable X
}
}
現在,為了Thread-3運行邏輯,它需要讀取變數X,如果是not synchronized(在同一監視器上),則X讀取的變數可能是舊值,因為它可能尚未更新Thread-1。
private void runLogic() {
if (X > 5) { // <-- Reading X here, can be inconsistent no
happens-before between atomic_increase and runLogic
} else {
}
}
我們本可以通過保持操作和方法happens-before之間的聯系來防止這種情況發生。如果是(在同一個監視器上),那么它必須等到變數被. 所以我們保證得到最后更新的值atomicrun_logicrunLogicsynchronizedXThread-1X
private void runLogic() {
synchronized (lock) {
if (X > 5) { // <-- Reading X here, will be consistent, since there
is happens-before between atomic_increase and runLogic
} else {
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/382668.html
