'锁'似乎无法在自定义同步集合中正常工作

时间:2017-02-22 09:04:38

标签: c# multithreading locking

我使用以下代码为同步集合创建SynchronizationRoot:

TSynchronizedArray.cs

public object SynchronizationRoot
{
    get
    {
        if(this._SynchronizationRoot == null)
        {
            Interlocked.CompareExchange<object>(ref this._SynchronizationRoot, new object(), null);
        }

        return this._SynchronizationRoot;
    }
}

这与.NET标准集合的实现非常相似。

下一个代码段是我用于向集合中添加项目并将其清除的地方(this._Items = T[]):

TSynchronizedArray.cs

public void Add(T Element)
{ 
    lock(SynchronizationRoot)
    {
        if (this._Count == this._Items.Length && !this.IsFixedSize)
        {
            if(this.Capacity <(this._Count + 1))
            {
                int NewCapacity = this.Capacity * 2;
                Capacity = NewCapacity;
            }
        }

        this._Items[this._Count++] = item;
    }
}

public void Clear()
{
    lock(SynchronizationRoot)
    {
        Array.Clear(this._Items, 0, this._Count);
        this._Count = 0;
        this._SerializationInfo = null;
    }
}

忽略_SerializationInfo,我认为此时它并不相关,只是为了ISerializable的实施。

现在到示例

Progam.cs

TSynchronizedArray<int> Array = new TSynchronizedArray<int>();

    Thread t1 = new Thread(new ThreadStart(() => {
        Parallel.For(0, 12, (i) => {
            Array.Add(1024 + i);

            if (i % 2 == 0)
            {
                Array.Clear();
            }
        });
    }));

    Thread t2 = new Thread(new ThreadStart(() => {
        Parallel.For(0, 12, (i) => {
            Array.Add(2024 + i);
        });
    }));

    Thread t3 = new Thread(new ThreadStart(() => {
        Parallel.For(0, 12, (i) => {
            Array.Add(3024 + i);
        });
    }));

    t1.Start();
    t2.Start();
    t3.Start();

    while (t1.IsAlive || t2.IsAlive || t3.IsAlive) ;

    for (int i = 0; i < Array.Count; i++)
    {
        Console.WriteLine(Array[i]);
    }

输出

1035
2024
2025
2026
2028
2029
2030
2031
2032
2033
2034
2035

3k +项目在哪里?有时候这个系列甚至只包含一些像2或3的东西。

为什么呢?据我所知,我正确地使用了锁,如果我使用System.Collections.ArrayList做同样的例子,它可以正常工作。

0 个答案:

没有答案
相关问题