请参阅下面的代码。我没有得到"伯爵"在主要作为" 5"总是。有人可以帮忙吗。
class Program
{
private static void Main(string[] args)
{
Thread t1 = new Thread(() => new Test("a"));
Thread t2 = new Thread(() => new Test("b"));
Thread t3 = new Thread(() => new Test("c"));
Thread t4 = new Thread(() => new Test("d"));
Thread t5 = new Thread(() => new Test("e"));
t1.Start();
t2.Start();
t3.Start();
t4.Start();
t5.Start();
t1.Join();
t2.Join();
t3.Join();
t4.Join();
t5.Join();
Console.WriteLine(Test.Names.Count);
}
}
public class Test
{
public static ListClass<string> Names { get; set; }
public Test(string name)
{
Console.WriteLine(name);
//Thread.Sleep(10);
if (Names == null)
Names = new ListClass<string>();
Names.Add(name);
}
}
public class ListClass<T>
{
private List<T> mylist = new List<T>();
private object myLock = new object();
public void Add(T item)
{
lock (myLock)
{
mylist.Add(item);
}
}
public int Count
{
get { return mylist.Count; }
private set
{ }
}
}
答案 0 :(得分:1)
有可能存在争用条件,这意味着在线程检查Names为null之间,另一个已经初始化它,从而覆盖它,将计数减少为新的集合。
在null检查周围设置一个锁,或者在测试类中使用静态构造函数来初始化集合,而不是最好的解决方案但是可以工作。
答案 1 :(得分:0)
if (Names == null)
{
lock(_sync)
{
if (Names == null)
{
Names = new ListClass<string>();
}
}
}
使用double-locking技术来避免竞争条件。
或者类Lazy<T>
,这对于这种情况非常有用。