[英]lock-free calc: how to sum N double numbers that are changing by other threads?
[英]how to synchronize addition from different threads using lock-free code?
我寫了NasdaqIndex
計算的簡單例子。 為簡單起見,我將其聲明為int
,這只是10
股票價格的總和。
class NasdaqIndex {
private int[] stockValue = new int[10]; // for simplicity let's assume they are already initialized
// just sum from 1 to 10 of stockValue
private int nasdaqIndexValue; // for simplicity let's assume that already initialized
public void StockValueUpdated(int stockValueIndex, int newValue) {
int diff = newValue - stockValue[stockValueIndex];
stockValue[stockValueIndex] = newValue;
nasdaqIndexValue += diff; // THIS NEED TO BE SYNCHRONIZED!
}
}
但在現實生活中,StockValueUpdated可以(並且將)從不同的線程並行調用不同的stockValueIndex(對於相同的stockValueIndex,它不會被稱為並行)。
所以我只需同步一行代碼nasdaqIndexValue += diff;
例如,如果一個線程執行nasdaqIndexValue += 10;
另一個線程執行nasdaqIndexValue += 3;
我需要確保添加完全正好13
。 在這種情況下我是否需要同步? 如果是這樣,如何使用無lock-free
代碼?
UPD oooops我剛剛意識到使用這樣的代碼我每次如果我使用雙打時都會向nasdaqIndex引入小“delta”。 所以我要么使用小數,要么我必須“完全重新計算”納斯達克指數,否則它將在一段時間后不等於股票總和。
使用Interlocked
類型將該操作作為原子操作:
Interlocked.Add(ref nasdaqIndexValue, diff);
使用volatile
關鍵字。
volatile修飾符通常用於多個線程訪問的字段,而不使用lock語句來序列化訪問。
private volatile int nasdaqIndexValue; // for simplicity let's assume that already initialized
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.