我使用以下代码为同步集合创建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
做同样的例子,它可以正常工作。