您问题中的代码是线程安全的恕我直言,但总的来说,该Interlocked.CompareExchange
方法比Interlocked.Exchange
实现无锁多线程的方法更灵活。以下是我希望对该方法进行编码的RunOnce
方式:
int _lock; // 0: not acquired, 1: acquired
public void RunOnce()
{
bool lockTaken = Interlocked.CompareExchange(ref _lock, 1, 0) == 0;
if (!lockTaken) return;
try
{
// Run code that should be executed by one thread only.
}
finally
{
bool lockReleased = Interlocked.CompareExchange(ref _lock, 0, 1) == 1;
if (!lockReleased)
throw new InvalidOperationException("Could not release the lock.");
}
}
我的建议是使用Monitor
该类:
object _locker = new();
public void RunOnce()
{
bool lockTaken = Monitor.TryEnter(_locker);
if (!lockTaken) return;
try
{
// Run code that should be executed by one thread only.
}
finally { Monitor.Exit(_locker); }
}
...或SemaphoreSlim
班级,如果您希望防止重入:
SemaphoreSlim _semaphore = new(1, 1);
public void RunOnce()
{
bool lockTaken = _semaphore.Wait(0);
if (!lockTaken) return;
try
{
// Run code that should be executed by one thread only.
}
finally { _semaphore.Release(); }
}
恕我直言,它使您的代码更清晰。