C# 为什么这4个线程在使用信号量时会锁定?

C# 为什么这4个线程在使用信号量时会锁定?,c#,multithreading,locking,semaphore,race-condition,C#,Multithreading,Locking,Semaphore,Race Condition,在一个可能有很多很多线程的系统中,我试图确保一次只实例化一个类的四个实例,并且可能在5-60秒后释放。实例在每个线程开始时创建,在线程中的进程结束时销毁 我还希望防止一次只构造一个实例。因此,我的逻辑是在对象实例化期间使用锁,但也用信号量包装整个线程逻辑 private static readonly object padlock = new object(); private static readonly Semaphore mutablelock = new Semaphore(0, 4)

在一个可能有很多很多线程的系统中,我试图确保一次只实例化一个类的四个实例,并且可能在5-60秒后释放。实例在每个线程开始时创建,在线程中的进程结束时销毁

我还希望防止一次只构造一个实例。因此,我的逻辑是在对象实例化期间使用锁,但也用信号量包装整个线程逻辑

private static readonly object padlock = new object();
private static readonly Semaphore mutablelock = new Semaphore(0, 4);

// called at the start of a long running thread
public static Object GetNewInstance()
{
    // semaphore used to prevent more than 4 objects from existing at any time
    mutablelock.WaitOne();

    // lock used to prevent more than one object being instantiated at a time
    lock (padlock)
    {
        var instance = new Object();
        return instance;
    }
}

// called at the end of a long running thread
public static void ReleaseInstance()
{
    mutablelock.Release();
}

该程序有四个线程(使用调试停止点查看时),每个线程都在
mutablelock.WaitOne()处停止行,不再前进。

您正在以保留所有条目的方式构建
信号量。政府这样说:

如果initialCount小于maximumCount,则效果与当前线程调用了
WaitOne
(maximumCount减去initialCount)次相同。如果您不想为创建信号量的线程保留任何条目,请对maximumCount和initialCount使用相同的数字

因此,做出以下改变:

private static readonly Semaphore mutablelock = new Semaphore(4, 4);

如果看不到任何调用
ReleaseInstance
,则只能假设并非所有需要在适当时间调用它的代码路径。为什么要阻止创建构造函数?这不是线程安全的。“多个”不是描述性的。有些人可能会认为50个线程是“多线程”。有些人可能会想象一万个线程。你对这个问题的描述听起来好像“多线程”中的四个以上线程不可能同时执行任何工作。如果是这样,那么为什么不使用四个线程呢?该段中的第一个“如果”似乎是多余的。