是否可以通过在属性访问器中使用Interlocked
来获取线程安全属性?
示例:
public class A()
{
private static long count;
public static long Count
{
get
{
return Interlocked.Read(ref count);
}
set
{
Interlocked.Exchange(ref count, value);
}
}
}
答案 0 :(得分:1)
运行上面的示例时,get
和set
访问器的执行行为是可线性化的。在不使用Interlocked
的情况下,get
和set
访问器的执行行为介于弱一致性和顺序一致性之间(即仅保证表现出弱一致性)。
当作为64位进程运行时,可以通过标记字段volatile
并使用简单的return语句和赋值运算符来完成相同的操作。但是,当作为32位进程运行时,volatile
64位字段上的操作不能保证是原子操作,因此需要使用Interlocked
来确保原子性。
答案 1 :(得分:1)
它不是线程安全的。试试这段代码:
long i
{
get { return Interlocked.Read(ref _i); }
set { Interlocked.Exchange(ref _i, value); }
}
long _i;
void Main()
{
Parallel.ForEach(Enumerable.Range(0, 1000_000),
//new ParallelOptions { MaxDegreeOfParallelism = 1},
x=>
{
i++;
});
i.Dump();
}
当运行此代码时,答案不是100_000,而是稍微低一点,证明它不是线程安全的。不知道为什么会发生这种情况