[英]How to make Java function atomic operation, and prevent calculation main thread interruption for handing results from another thread
[英]Is assignment and function value calculation an atomic operation?
我想知道函數值的計算以及將結果分配給變量是否在Java中是原子操作。
例如:
我有一個線程安全優先級隊列q
。 在q
我保存元素,每個元素都有一個根據其在隊列中放置的rank
。 另外,我有一個共享變量topRank
,該變量應始終包含q
最頂層元素的等級。 以下代碼按線程數並行執行:
element = q.remove(); // do something with element
topRank = q.peek();
可能發生的情況是threadA將從q
刪除一個元素並計算q.peek()
值,就在將其分配給topRank
之前, topRank
會中斷它,然后threadB將從q
刪除另一個元素並更新topRank
。 然后的ThreadA將恢復到不正確的值到分配topRank
。
與官方文獻的鏈接將不勝感激。
謝謝。
簡短的答案是這些操作不是原子操作,您需要將同步寫入代碼中。 這是一個巨大的主題,有關編寫線程安全程序的知識很多。 Google表示“ java線程安全”和“ java多線程”。
線程安全性只是指操作中 remove()
或peek()
調用。 除非您采取措施阻止線程相互競爭, topRank
使用topRank
是完全可能的。
有關更多信息,請參閱Java同步教程 。
1)我認為沒有原子操作,除非您保護它們(同步和其他技術)。
2)也就是說,它不適用於您的示例。
在您的示例中,您有。
a)致電q.remove()
b) q.remove()
完成其工作(是否線程安全)。
c) q.remove()
返回結果
d)將結果分配給element
(這是分配!!!!!!!!!!)
因此,不僅分配(操作的最后一步)是否是原子的,還需要確保q.remove()也是原子的。 我向您保證不是。
由於它不是線程安全的,因此如果要避免並發訪問,則應同步整個塊。
編輯回答作者的評論。
因此,您要問的是, q.peek()
是否會以某種方式返回一個元數據,但另一個會由於其他線程將其topRank
而以topRank
結尾,不是嗎?
除非不同線程共享topRank
,否則不可能:
a) q.peek()
運行其邏輯
b)復制q.peek()
)的返回值(存儲在堆棧中,返回到名為q.peek()
表達式)
c) q.peek()
退出。 現在只有其他實例可以訪問同步部分以更改q.state,但是返回值已復制到堆棧中。
d)將堆棧中的副本分配給topRank
函數值的計算不可能是原子的。 該函數在返回值之前可以運行數年。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.