线程没有等待

时间:2015-08-02 15:36:18

标签: c# multithreading

请参阅下面的代码。我没有得到"伯爵"在主要作为" 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
        { }
    }
}

2 个答案:

答案 0 :(得分:1)

有可能存在争用条件,这意味着在线程检查Names为null之间,另一个已经初始化它,从而覆盖它,将计数减少为新的集合。

在null检查周围设置一个锁,或者在测试类中使用静态构造函数来初始化集合,而不是最好的解决方案但是可以工作。

答案 1 :(得分:0)

if (Names == null) 
{
    lock(_sync)
    {
        if (Names == null)
        {
            Names = new ListClass<string>();
        }
    }
}

使用double-locking技术来避免竞争条件。 或者类Lazy<T>,这对于这种情况非常有用。