日期:2014-05-19  浏览次数:20713 次

多线程集合安全性问题
有个公共集合集合ArrayList   m_arryList;
现在多线程操作和访问这个集合变量
如何在其他线程对m_arryList增加或减少Items时,保证其他线程枚举时(foreach...)不会出错?

------解决方案--------------------
把对集合的访问保护起来lock(),这样就可以不出错了,是一个互斥的问题
------解决方案--------------------
线程同步
------解决方案--------------------
任何一个 使用的时候都要锁住变量,
------解决方案--------------------
lock(this){
代码
}
------解决方案--------------------
每个线程操作m_arryList都这样:
Lock(ListView1)
{
....m_arryList....;

}
这样就OK了,不会有冲突的问题

lock关键字可将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下:

lock(expression) statement_block
其中:

expression
指定要锁定的对象。expression必须是引用类型。
通常,如果要保护实例变量,则expression为this;如果要保护static变量(或者如果临界区出现在给定类的静态方法中),则expression为typeOf(class)。

statement_block
临界区的语句。
摘自msdn
lock (this)只保护本实例
------解决方案--------------------
代码如下,其中枚举时(foreach...)的方法二更好,加锁时间短于方法一.

ArrayList m_arryList = new ArrayList();

//在线程A中运行
private void AddOrRemove()
{
lock (m_arryList.SyncRoot)
{
Object theItem = new object();

m_arryList.Add(theItem);
m_arryList.Remove(theItem);
}
}


//在线程B中运行: 方法一.
private void EnumArrayList()
{
lock (m_arryList.SyncRoot)
{
foreach (Object theItem in m_arryList)
{
Console.WriteLine(theItem.ToString());
}
}
}

//在线程B中运行: 方法二
private void EnumArrayList2()
{

lock (m_arryList.SyncRoot)
{
Object[] objects = new object[m_arryList.Count];
m_arryList.CopyTo(objects);
}


foreach (Object theItem in objects)
{
Console.WriteLine(theItem.ToString());
}

}