多级锁?

Multi level lock?

玩并行处理,我有一个 Parallel.For 循环,它对可枚举对象进行查找,如果找不到它要查找的内容,则添加它。不过,我一直 运行 关注一个线程修改可枚举对象而另一个线程正在执行查找的问题,这会引发异常。显而易见的解决方案是在查找和条目上都使用 lock ,但这有点蛮力。我希望它能够 运行 多个并发查找,所以我不想在一个线程进行查找时完全锁定它,但我确实想禁止它在查找时进行添加正在处理。有没有办法做这样的两级锁?

我会考虑使用某种形式的不可变集合和 Interlocked 来替换共享实例。

例如你提到 "Look ups" 那么 ImmutableDictionary 可能是一个很好的匹配吗?

然后对于查找和更新,你有类似的东西:

var local = sharedReference;
while(!local.ContainsKey(lookupValue))
{
    var newValue = /* Whatever */
    var newLocal = local.Add(lookupValue,newValue);
    var result = Interlocked.CompareExchange(ref sharedReference, newLocal, local);
    if(result == local) break;
    local = result;
}
//At this point, local definitely contains a key for lookupValue

您可能想要使用 ReaderWriterLock

private ReaderWriterLockSlim lock = new ReaderWriterLockSlim();

public string Read () {
    lock.EnterReadLock ();
    try {
        return "xxx";
    } finally {
        lock.ExitReadLock();
    }
}

public void Write () {
    lock.EnterWriteLock ();
    try {
        // ...
    } finally {
        lock.ExiteWriteLock ();
    }
}

多个线程可以拥有 ReaderWriterLock 的 "reader" 部分,但只有一个线程可以拥有 "writer" 部分(并且有 writer 时不能有 reader)。