在c# get和set中使用互锁是线程安全的
本文关键字:线程 安全 get set | 更新日期: 2023-09-27 18:05:50
是否可以通过在属性访问器中使用Interlocked
来获得线程安全属性?
的例子:
public class A()
{
private static long count;
public static long Count
{
get
{
return Interlocked.Read(ref count);
}
set
{
Interlocked.Exchange(ref count, value);
}
}
}
当上面的例子运行时,get
和set
访问器的执行行为是线性的。在不使用Interlocked
的情况下,get
和set
访问器的执行行为介于弱一致性和顺序一致性之间(即只保证表现弱一致性)。
作为64位进程运行时,可以通过标记字段volatile
并使用简单的返回语句和赋值操作符来完成相同的操作。但是,当作为32位进程运行时,不能保证对volatile
64位字段的操作是原子性的,因此需要使用Interlocked
来确保原子性。
这不是线程安全的。试试下面的代码:
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();
}
当您运行这段代码时,答案不是1000_000,而是稍微低一点,证明它不是线程安全的。不知道为什么会这样