c# - C# 中的条件线程锁

标签 c# multithreading concurrency locking

当基础条件不恒定时是否可以有条件线程锁?

我有两个函数 A 和 B,以及一个决定执行哪个函数的条件。 A本身是线程安全的,对A的多个调用可以同时执行,B则不是,并且是同步的。但在执行 B 期间,条件可能会发生变化(从 false 变为 true),因此当时执行 A 的所有线程都会抛出错误。

if (condition)
{
    A();
}
else
{
    B();
}

A - thread safe
B - Synchronized using [MethodImpl(MethodImplOptions.Synchronized)]

因此,我正在寻找一种方法来锁定 A,但仅在 B 运行时锁定。 请建议一种实现此目的的方法。

一些详细说明: 我正在创建一个缓存,性能非常关键,因此毯子锁不可行。

条件是请求的数据是否存在于缓存中。

A() = AddToUpdates() - 在缓存命中时执行,仅使用并发字典添加特定缓存键的更新数量。

B() = ProccessUpdates() 和 EvictLeastPriorityEntry() - 在缓存未命中时执行,将处理所有先前的更新,并且将重新安排存储缓存条目顺序的底层数据结构。

然后优先级最低的条目将被删除。

正如已接受的答案中所提到的,ReaderWriterLock 似乎是可行的方法。

不过有一个问题, 假设,线程 1 开始执行并且发生缓存命中(在优先级最低的条目上),这意味着 if 条件为 true 并进入 if block 。但在调用A()之前,控制权被切换到thread2。

线程2 - 发生缓存未命中,执行重新排序和逐出(线程1 中的A() 需要访问的条目)。

现在当controls返回到thread1时,会发生错误。

这是我认为应该有效的解决方案:

_lock.EnterReadLock();
if (condition)
{
    A();
}
_lock.ExitReadLock();

if (!condition)
{
    B();
}

void A()
{
   // ....
}

void B()
{
    _lock.EnterWriteLock();
    // ...
    _lock.ExitWriteLock();
}

这行得通吗?

谢谢。

最佳答案

我可能解决您的问题的方法可能是 ReaderWriterLockSlim类(class)。这是一种同步原语,允许多个并发读取器或一个独占写入器,但不能同时支持这两者。

Use ReaderWriterLockSlim to protect a resource that is read by multiple threads and written to by one thread at a time. ReaderWriterLockSlim allows multiple threads to be in read mode, allows one thread to be in write mode with exclusive ownership of the lock, and allows one thread that has read access to be in upgradeable read mode, from which the thread can upgrade to write mode without having to relinquish its read access to the resource.

示例:

private readonly ReaderWriterLockSlim _lock = new();

void A()
{
    _lock.EnterReadLock();
    try
    {
        //...
    }
    finally { _lock.ExitReadLock(); }
}

void B()
{
    _lock.EnterWriteLock();
    try
    {
        //...
    }
    finally { _lock.ExitWriteLock(); }
}

关于c# - C# 中的条件线程锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72930129/

相关文章:

c - Telnet session ,fork 与 thread

javascript - HTML5 Web Worker 是线程还是进程?

c# - 在文本中查找查询匹配项

c# - 在 .Net 运行时为测试用例散列 float

c# - 如何将引发的异常从C#类传递到C#表单

java - 我怎样才能停止我的申请?

java - 执行人服务。当所有线程都终止时如何等待

c# - 如何使用 Parallel.For/ForEach 获得最佳性能? (包括表演时间)

asp.net - 高并发系统中的缓存访问

java - list 3.7 在实践中如何在 java 并发中工作?