我正在创建一个自定义的CountdownWaitHandle类,它有以下方法:
public void Signal()
{
if (Interlocked.Decrement(ref threadsInstances) <= 0)
{
mre.Set();
}
}mre是ManualResetEvent类的一个实例,我使用这个类来阻塞当前线程,并等待所有线程完成其工作或在完成其工作或发生异常调用信号()方法时完成其工作。
,所以我的问题是Interlock.Decrement和条件(<=0)的返回值是否会在if条件内引起任何并发问题?或我必须对if条件使用lock语句,如果主体而不是互锁,如上面所示:
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类为任何云站点使用块下载一个大文件。因此,每个块在下载完他的范围字节后,就会释放资源或转移到另一个Stream。
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();
}发布于 2017-03-23 17:25:22
假设您调用Interlocked.Decrement以将计数提高到零以上,则此示例中的Interlocked.Increment将按预期工作。
当然,使用CountdownEvent比构建自己的同步对象更好。
https://stackoverflow.com/questions/42978642
复制相似问题