多线程访问字符串列表,指针在每次访问时移动

时间:2018-12-28 00:15:57

标签: c# .net

我有一个列表,可以说它确实有10个字符串。我将启动线程,一旦线程访问列表中的条目,我希望指针移动,因此当下一个线程想要访问它时,它将访问下一个项目。当我们位于列表的底部时,指针将移至顶部。请告知我该怎么做。 线程将不会插入任何内容,只是读取,并且在运行时字符串列表不会更改,而是静态的。

2 个答案:

答案 0 :(得分:2)

您可以使用lock statement

  

lock语句获取给定的互斥锁   对象,执行一个语句块,然后释放锁。而   持有锁后,持有锁的线程可以再次获取并   释放锁。任何其他线程被阻止获取锁   并等到锁被释放。

private static readonly object Sync = new object();
private int _index = 0;
private readonly List<string> _list = new List<string>() { "blah" ... };

...

public string SafeGetNext()
{
   lock (Sync)
   {
      try
      {
         return _list[_index];
      }
      finally
      {
         _index = _index >= _list.Count - 1 ? 0 : _index + 1;
      }
   }
}

Christopher Pisz的好评

  

我认为指出什么需要锁定很重要   什么没有,为什么。 OP会带走他需要锁定的东西吗   只读数据?应该吗有什么东西要写吗?有没有   差异?

在这种情况下,lock在读取周围和索引修饰符中形成障碍。在这种情况下,两者都很重要。

原因是,两个操作(在这种情况下)都必须是原子的(松散地使用)。意思是一次读取以及相关的修改后的索引需要作为一个块完成,并且在所有线程之间是互斥的。

以另一种方式,仅锁定索引修改没有意义,因为2个线程可以读取相同的值。同样,相反地,仅锁定读取是没有意义的,因为2个线程可能具有相同的索引缓存值,并且将尝试对其进行更新,从而导致错误的索引。

答案 1 :(得分:0)

怎么样?

public class StringListManager
{
    private readonly object _lock = new object();
    private readonly List<string> _theStrings = new List<string>();
    private int _index = 0;

    //maybe you want to do this in a constructor??
    public void Initialize(IEnumerable<string> strings)
    {
        lock (_lock)
        {
            _theStrings.AddRange(strings);
        }
    }

    public string GetNextString()
    {
        lock (_lock)
        {
            var count = _theStrings.Count;
            if (count == 0)
            {
                return null; //or an empty string, your choice
            }

            var result = _theStrings[_index];
            ++_index;
            if (_index >= count)
            {
                _index = 0;
            }

            return result;
        }
    }

    public void ClearStrings()
    {
        lock (_lock)
        {
            _theStrings.Clear();
        }
    }
}

它可以编译,但是没有经过很好的测试。