假设我们在C#中有一个可以从多个线程访问的数组,在运行时更改这个数组是否可以安全? (不是改变其数据,而是改变指针)。换句话说,是将数组指针写成原子操作吗?
答案 0 :(得分:6)
写一个新指针的地址是一个原子操作:
5.5变量引用的原子性
以下数据类型的读写是原子的:bool,char,byte,sbyte,short,ushort,uint,int,float和reference类型。此外,在先前列表中具有基础类型的枚举类型的读取和写入也是原子的。其他类型的读写,包括long,ulong,double和decimal,以及用户定义的类型,都不能保证是原子的。
由于数组指针是引用,因此它是线程安全的。
为了避免缓存副作用,您也可以使用volatile
关键字。
但是你必须非常小心。假设你有一个方法:
public class Foo {
private volatile int[] data;
public void Method () {
for(int i = 0; i < data.length; i++) {
data[i] = i;
}
}
public void OtherMethod (int[] data) {
this.data = data;
}
}
假设您将data
数组设置为具有不同长度的数组,for
- 循环可能会检查长度获取旧数组的长度,然后将引用修改为一个较短的数组,然后你访问一个非法的索引。
非阻塞多线程应用程序因此将引用的副本复制到数组中,修改数组,然后检查引用是否被修改。