不安全的例子
cs
/// <summary>
/// 不安全的例子
/// </summary>
static void unSalfe()
{
List<int> mylist = new List<int>();
var t = Task.Run(()=>{
Thread.Sleep(2000);
for(int i=0; i<20; i++)
{
mylist.Add(3);
Thread.Sleep(1);
}
System.Console.WriteLine($"task: list size:{mylist.Count}");
});
Thread.Sleep(2000);
for(int i=0; i<50; i++)
{
Thread.Sleep(1);
mylist.Add(6);
}
//正确的结果应该是70,结果有可能正确也有可能不正确,多运行几次就能看到效果
System.Console.WriteLine($"main: list size:{mylist.Count}");
t.Wait();
}
测试不出来可以注释 Thread.Sleep(2000);
或者增加for循环数量
锁的方式保证安全
cs
static void salfe()
{
List<int> mylist = new List<int>();
var t = Task.Run(()=>{
Thread.Sleep(2000);
lock((mylist as ICollection).SyncRoot)
{
for(int i=0; i<20; i++)
{
mylist.Add(3);
Thread.Sleep(1);
}
System.Console.WriteLine($"task: list size:{mylist.Count}");
}
});
Thread.Sleep(2000);
lock((mylist as ICollection).SyncRoot)
{
for(int i=0; i<50; i++)
{
Thread.Sleep(1);
mylist.Add(6);
}
//正确的结果应该是70
System.Console.WriteLine($"main: list size:{mylist.Count}");
}
t.Wait();
}
线程安全的队列
cs
/// <summary>
/// 安全的队列
/// </summary>
static void salfeQueue()
{
var mylist = new ConcurrentQueue<int>();
var t = Task.Run(()=>{
Thread.Sleep(2000);
for(int i=0; i<20; i++)
{
mylist.Enqueue(3);
Thread.Sleep(1);
}
System.Console.WriteLine($"task: list size:{mylist.Count}");
});
Thread.Sleep(2000);
for(int i=0; i<50; i++)
{
Thread.Sleep(1);
mylist.Enqueue(6);
}
//正确的结果应该是70
System.Console.WriteLine($"main: list size:{mylist.Count}");
t.Wait();
//取出数据
//mylist.TryDequeue(out int a);
}
线程安全的无序列表
cs
/// <summary>
/// 安全的无序数据
/// </summary>
static void salfeBag()
{
var mylist = new ConcurrentBag<int>();
var t = Task.Run(()=>{
Thread.Sleep(2000);
for(int i=0; i<20; i++)
{
mylist.Add(3);
Thread.Sleep(1);
}
System.Console.WriteLine($"task: list size:{mylist.Count}");
});
Thread.Sleep(2000);
for(int i=0; i<50; i++)
{
Thread.Sleep(1);
mylist.Add(6);
}
//正确的结果应该是70
System.Console.WriteLine($"main: list size:{mylist.Count}");
t.Wait();
//取出数据
//mylist.TryTake(out int a);
}