多线程、锁定和字符串值列表

本文关键字:列表 字符串 锁定 多线程 | 更新日期: 2023-09-27 18:28:47

我有一个有许多线程的应用程序,其中每个线程对GUID引用的资源执行一些操作,其中所述GUID作为字符串存储在列表中。任何时候都只能对GUID引用的资源执行一个操作。

我正在尝试使用锁定语句和一个简单的列表。我遇到的问题是,我似乎无法安全地检查列表是否包含锁定语句中的GUID,然后用另一个锁定语句将其添加到列表中。看起来,当有多个线程时,每个线程都会检查GUID是否在列表中,并且检查结果都为false时,它们都会添加GUID(明显的问题)。

此外,我不能将检查与将GUID添加到字符串列表的语句放在同一个锁中,因为如果我这样做,锁将被保留,从而阻止其他正在处理该资源的线程将其从列表中删除(他们无法获得锁)。

我希望你能原谅我的原始示例,但我不知道如何在多线程环境中可靠地测试和安全地锁定。不幸的是,我也不能随意为我的客户更改应用程序的设计。

如果你有一个类/库可以推荐,请举一个小例子。

private static readonly object _guidLock = new object();
private static List<string> guidList = new List<string>();
public static bool isGuidLocked(string guid)
{
    lock (_guidLock)
    {
        if (guidList.Contains(guid)) return true;
        return false;
    }
}
public static bool lockGuid(string guid)
{
    while (isGuidLocked(guid)) { }
    lock (_guidLock)
    {
        guidList.Add(guid);
    }
    return true;
}
public static bool releaseGuid(string guid)
{
    lock (_guidLock)
    {
        guidList.Remove(guid);
    }
    return true;
}
public static void doWorkOnGuid(string guid)
{
    lockGuid(guid);
    // do something there
    releaseGuid(guid);
}

多线程、锁定和字符串值列表

不要使用列表。NET提供线程安全集合。

在这种情况下,您可能希望ConcurrentDictionary使用GUID作为密钥。

请参阅命名空间:System.Collections.Concurrent

System.Collections.Concurrent命名空间提供了应该用来代替的线程安全集合类System.Collections和System.Collections.Generic命名空间,只要有多个线程同时访问集合。

在这种情况下使用基于时间戳的并发控制技术。使用一个静态变量_guidListUpdateTime,它将保存最新的_guidList修改时间。类似地,为每个线程分配一个读取时间戳值。现在,在将guid添加到列表时,检查当前线程读取时间戳是否大于_guidListUpdateTime。如果是,则将guid添加到guidList,否则不添加。https://www.classle.net/book/timestamp-based-protocol