在 If 条件中使用 Interlocked.Decrement 是否会导致任何并发问题?
Using Interlocked.Decrement inside If condition, could it cause any Concurrency Issue?
我正在创建自定义 CountdownWaitHandle class 它具有以下方法:
public void Signal()
{
if (Interlocked.Decrement(ref threadsInstances) <= 0)
{
mre.Set();
}
}
mre 是 ManualResetEvent class 的一个实例,我使用这个 class 来阻塞当前线程并等待所有线程完成他的工作,每个线程完成他的工作或发生异常调用Signal() 方法。
所以我的问题是 Interlock.Decrement 和 condition(<=0) 的 return 值是否会导致 if condition? 中的任何并发问题? 或者我必须对 if 条件和 if body 使用 lock 语句而不是 Interlock,如上例所示:
lock(_lock)
{
if (--threadsInstances <= 0)
{
mre.Set();
}
}
注意:我用的是3.5网
完整代码:
public class CountdownWaitHandle : WaitHandle
{
private int threadsInstances = 0;
private ManualResetEvent mre;
private readonly object threadsyncAccess = new object();
public CountdownWaitHandle(int initialCount)
{
threadsInstances = initialCount;
mre = new ManualResetEvent(false);
}
public void AddCount()
{
Interlocked.Increment(ref threadsInstances);
}
public void Signal()
{
if (Interlocked.Decrement(ref threadsInstances) <= 0)
{
mre.Set();
}
}
public override bool WaitOne()
{
return mre.WaitOne();
}
}
在这个例子中。
我将使用我的自定义 CountdownEvent class 下载一个大的
文件使用任何云站点的块。所以每个块在完成下载其范围字节后释放资源或移动到另一个流。
public static void Main(String[] args)
{
CountdownWaitHandle customCountDown = new CountdownWaitHandle(0)
while (i < 100)
{
SpecificWork work1 = new SpecificWork (startPosition, endPosition, customCountDown);
customCountDown.AddCount();
ThreadPool.QueueUserWorkItem(PerformTask, work1); // after finish download it invokes to Signal method.
}
customCountDown.WaitOne();
}
Interlocked.Decrement
将按此示例中的预期工作,假设您正在调用 Interlocked.Increment
以将计数提高到零以上。
当然,使用 CountdownEvent
会比构建自己的同步对象更好。
我正在创建自定义 CountdownWaitHandle class 它具有以下方法:
public void Signal()
{
if (Interlocked.Decrement(ref threadsInstances) <= 0)
{
mre.Set();
}
}
mre 是 ManualResetEvent class 的一个实例,我使用这个 class 来阻塞当前线程并等待所有线程完成他的工作,每个线程完成他的工作或发生异常调用Signal() 方法。
所以我的问题是 Interlock.Decrement 和 condition(<=0) 的 return 值是否会导致 if condition? 中的任何并发问题? 或者我必须对 if 条件和 if body 使用 lock 语句而不是 Interlock,如上例所示:
lock(_lock)
{
if (--threadsInstances <= 0)
{
mre.Set();
}
}
注意:我用的是3.5网
完整代码:
public class CountdownWaitHandle : WaitHandle
{
private int threadsInstances = 0;
private ManualResetEvent mre;
private readonly object threadsyncAccess = new object();
public CountdownWaitHandle(int initialCount)
{
threadsInstances = initialCount;
mre = new ManualResetEvent(false);
}
public void AddCount()
{
Interlocked.Increment(ref threadsInstances);
}
public void Signal()
{
if (Interlocked.Decrement(ref threadsInstances) <= 0)
{
mre.Set();
}
}
public override bool WaitOne()
{
return mre.WaitOne();
}
}
在这个例子中。
我将使用我的自定义 CountdownEvent class 下载一个大的
文件使用任何云站点的块。所以每个块在完成下载其范围字节后释放资源或移动到另一个流。
public static void Main(String[] args)
{
CountdownWaitHandle customCountDown = new CountdownWaitHandle(0)
while (i < 100)
{
SpecificWork work1 = new SpecificWork (startPosition, endPosition, customCountDown);
customCountDown.AddCount();
ThreadPool.QueueUserWorkItem(PerformTask, work1); // after finish download it invokes to Signal method.
}
customCountDown.WaitOne();
}
Interlocked.Decrement
将按此示例中的预期工作,假设您正在调用 Interlocked.Increment
以将计数提高到零以上。
当然,使用 CountdownEvent
会比构建自己的同步对象更好。