【发布时间】:2018-08-15 10:49:56
【问题描述】:
我们遇到了一些性能问题,正在考虑从一些频繁使用的属性中取出一些线程安全锁。更准确地说,仅来自访问修饰符 getter。改进之处在于,如果其他线程正在获取同一属性,则 setter 访问修饰符不再“阻塞”。
-> 当然,必须确保如果假设对于整数类型,例如位值 11110011,即 243,则一旦开始写入,所有位都会被写入。必须确保写入线程永远不会未完成,并且获取线程会变成一些半写入位,从而导致错误值。是这样的吗?
如果是这样,该概念是否适用于所有 .net 内置数据类型,也适用于字符串?
请参阅以下显示概念的代码示例:
// for properties used just the "Built-In Types"
// doc: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/built-in-types-table
private int _ActualValue = 0;
private readonly object _Lock_ActualValue = new object();
public int ActualValue
{
get
{
//lock(_Lock_ActualValue) <- remove lock for access modifier get ?
//{
return _ActualValue;
//}
}
set
{
lock (_Lock_ActualValue)
{
if((value != _ActualValue) && (value < 1000))
{
Log("_ActualValue", value.ToString());
_ActualValue = value;
}
}
}
}
【问题讨论】:
-
你为什么要使用
lock?为什么不使用Interlocked方法? stackoverflow.com/questions/24808291/… -
整数和引用的对齐读/写在 .net 中是原子的,所以是的,您不会得到损坏的数据。也就是说,这个锁不太可能是性能问题,除非它得到非常的竞争。我建议您首先在您的应用程序上运行分析器以找出瓶颈是什么
-
另外,如果你使用
lock,我建议将日志移到lock之外。这可能意味着某些日志记录出现故障,但由于争用减少,性能将得到改善。 -
是什么让您得出结论,这些锁的争用是您的性能问题@spaghettiBox?
-
同意凯文·戈斯的观点;您是否进行了分析以确定瓶颈在哪里?有很多线程都在等待读取同一个属性,而且时间很长(足以引起问题),这似乎是不寻常的。
标签: c# multithreading properties thread-safety