如何解决多线程中正确的数据访问
我有多个线程同时使用的Method。该线程中的每个线程都调用另一种方法来从列表中接收所需的数据(每个方法应该获得不同的数据)。
我编写了这段代码以从列表中获取数据,并在线程中使用它们。
public static List<string> ownersID;
static int idIdx = 0;
public static string[] GetUserID()
{
if (idIdx < ownersID.Count-1)
{
string[] ret = { ownersID[idIdx],idIdx.ToString() };
idIdx++;
return ret;
}
else if (idIdx >= ownersID.Count)
{
string[] ret = { "EndOfThat" };
return ret;
}
return new string[0];
}
然后每个线程使用此代码接收数据并将其从列表中删除:
string[] arrOwner = GetUserID();
string id = arrOwner[0];
ownersID.RemoveAt(Convert.ToInt32(arrOwner[1]));
但是有时2个或更多线程可以具有相同的数据。 有没有更好的方法可以做到这一点?
解决方法
如果要使用List进行操作,只需添加一点锁定即可
private object _lock = new object();
private List<string> _list = new List<string>();
public void Add(string someStr)
{
lock(_lock)
{
if (_list.Any(s => s == someStr) // already added (inside lock)
return;
_list.Add(someStr);
}
}
public void Remove(string someStr)
{
lock(_lock)
{
if (!_list.Any(s => s == someStr) // already removed(inside lock)
return;
_list.Remove(someStr);
}
}
这样,没有线程会添加/删除任何东西,而另一个线程也是如此。您的列表将受到保护,免受多线程访问。并且您确保只有一种。不过,您可以使用ConcurrentDictionary<T1,T2>
更新:由于此MSDN线程安全声明,我删除了锁定前检查
,对列表执行多次读取操作(读取-多线程)是安全的,但是如果在读取集合时对其进行了修改,则会出现问题。
在更大范围的应用程序中,您可以使用.Net队列在两个线程之间进行通信。 使用队列的好处是您不需要锁定对象,这将减少延迟。从主线程到线程A,线程B和线程C,数据将通过队列添加和接收。无需锁定。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。