多线程集合安全性问题
有个公共集合集合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());
}
}