Giu*_*olo 1 .net c# windows-services thread-safety reentrancy
以下代码是可重入的吗?
它是否是线程安全的,如果this.NextToExecuteIndex声明private int NextToExecuteIndex = 0;并且不在其他地方计算?
protected override void Poll(object sender, System.Timers.ElapsedEventArgs e)
{
int index;
object locker = new object();
lock (locker)
{
Interlocked.Increment(ref this.NextToExecuteIndex);
if (this.NextToExecuteIndex >= this.ReportingAgentsTypes.Count())
{
this.NextToExecuteIndex = 0;
}
index = this.NextToExecuteIndex;
}
var t = this.ReportingAgentsTypes[index];
Console.WriteLine(t.ToString());
}
Run Code Online (Sandbox Code Playgroud)
不,这根本不是线程安全的.锁定无效,因为该对象是线程的本地对象.它需要由所有调用线程共享.修复后,您不需要使用互锁增量,因为锁序列执行.
作为一般规则,您应该locker与您要保护的资源放在同一级别.如果资源由实例拥有,则应该如此locker.同样,如果资源归类所有.
至于重入,lock关键字使用可重入锁,即如果该线程持有锁,则允许相同线程.这可能不是你想要的.但是如果你有一个不可重入的锁定,那么你就会因为重入的呼叫而陷入僵局.我也不认为你也想要那个.
你看起来想要一个环绕增量.只要集合没有被修改,就可以通过互锁操作实现,即无锁定.如果是这样,那么可以这样写:
do
{
int original = this.NextToExecuteIndex;
int next = original+1;
if (next == this.ReportingAgentsTypes.Count())
next = 0;
}
while (Interlocked.CompareExchange(ref this.NextToExecuteIndex, next, original) != original);
Run Code Online (Sandbox Code Playgroud)
注意:您应该声明NextToExecuteIndex为volatile.
| 归档时间: |
|
| 查看次数: |
1037 次 |
| 最近记录: |