我确信这个问题会被问很多次,但我想澄清这个概念。
最近,当两个线程在两个不同的函数中访问同一列表时,我遇到了一个错误。如果我没有正确的锁定,在什么情况下会导致问题?即使我在第二个函数中有锁并且两个线程不相关,但它们正在操作相同的列表。一种是添加,另一种是与空列表交换。什么情况下会捕获异常?请帮忙。
伪代码:
List<SomeClass> list=new List<SomeClass>();
object mutex=new object();
Run Code Online (Sandbox Code Playgroud)
线程 1 访问该函数并修改列表:
public void Manipulate()
{
//some operation
list.add(new SomeClass());
}
Run Code Online (Sandbox Code Playgroud)
线程 2 访问该函数并清除列表:
public void SwapList()
{
List<SomeClass> cls=new List<SomeClass>();
try
{
while(Thread2.isAlive)
{
//some operation
if(list.Count()>0)
{
lock(mutex)
{
swap(ref list,ref cls)
}
}
}
}
catch(exception ex)
{
}
}
public void swap(List<SomeClass> a, List<SomeClass> b)
{
List<SomeClass> temp=a;
a=b;
b=temp;
}
Run Code Online (Sandbox Code Playgroud)
如果我没有正确的锁定,在什么情况下会导致问题?
每当至少有两个线程同时访问数据并且其中至少一个正在写入时。
因此,只要有一些可以从多个线程访问的数据,就应该锁定。您需要锁定对该数据的每次访问。
作为替代方案,您可以使用线程安全的数据结构(如 中的集合System.Collections.Concurrent)。如果你这样做了,你就不必担心自己被锁,因为结构已经正确地(并且有效地)做到了这一点。