【问题标题】:Multithreading, locking, and a list of string values多线程、锁定和字符串值列表
【发布时间】:2016-01-04 04:43:25
【问题描述】:

我有一个具有许多线程的应用程序,其中每个线程对由 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);
}

【问题讨论】:

  • 您是否正在寻找正确的方法或解释为什么您的代码不太可能正常工作? (您可能想查看“双重检查锁定”以了解如何使您的代码正常工作)
  • 我很想更好地了解正确的方法,看看我是否可以正确整合它。

标签: c# multithreading concurrency


【解决方案1】:

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

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

查看命名空间:System.Collections.Concurrent

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

【讨论】:

  • 示例我如何处理上面“lockGuid”中的“等待和添加”案例?
  • 您无需手动等待。我想你想要 ConcurrentDictionary 上的 TryAdd() 方法。如果 GUID 不存在并被添加,它将返回 true,否则返回 false。
  • 即while (!TryAdd(...)) { } 会做我需要的吗?
  • 是的,可以的。请记住,无限期阻塞代码可能是危险的。您可能还需要一个小的 Thread.Sleep,这样它就不会尽可能快地敲击字典,直到能够添加为止。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    相关资源
    最近更新 更多