我编写了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”,如果我使用的是双打。所以我要么使用小数,要么我必须“完全重新计算”纳斯达克指数,否则它不会等于一段时间后的股票总和。
答案 0 :(得分:1)
使用Interlocked
类型将该操作设为原子操作:
Interlocked.Add(ref nasdaqIndexValue, diff);
答案 1 :(得分:1)
使用volatile
关键字。
volatile修饰符通常用于访问的字段 多个线程,不使用lock语句来序列化访问。
private volatile int nasdaqIndexValue; // for simplicity let's assume that already initialized