我想知道这段代码是否线程安全,如果不是,我该如何使其线程安全。这段代码被一个定时器调用:
private volatile bool _isSynchronizing;
private void SynchronizeSessionCache(object state = null)
{
if (_isSynchronizing)
{
Log.Warn($"Aborted synchronization of SessionCache with SessionManager because we are already synchronizing. Interval is: {SynchronizationInterval}");
return;
}
_isSynchronizing = true;
bool lockWasTaken = false;
try
{
// some code that doesn't need a lock ...
// ...
// lock this part
Monitor.Enter(_lockObject, ref lockWasTaken);
// main code ...
}
finally // omitted catch
{
_isSynchronizing = false;
if(lockWasTaken)
Monitor.Exit(_lockObject);
}
}
我的担忧是,一个线程在方法开头检查
_isSynchronizing
,此时它是false
。然后另一个线程进入该方法体,因为它还没有被线程1设置为true
。即使_isSynchronizing
是volatile
,这种情况是否可能?如果是,最好的方法是什么,以使该方法线程安全?如果我理解正确,
volatile
不能防止这种竞态条件,但只能确保变量不会被缓存,因此所有线程始终读取当前值。
_lockObject
在其他需要访问共享资源的方法和事件中也被使用。在同步期间必须锁定它。绝不能发生多个线程同时进入的情况。这就是为什么我使用_isSynchronizing
标志的原因。 - Tim Schmelter_isSynchronizing
改为int
类型,然后编写if (Interlocked.CompareExchange(ref _isSynchronizing, 1, 0) != 0)
代码。这样就可以解决问题而不需要使用锁。 - Lucas Trzesniewski