不安全的例子
/// <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循环数量
锁的方式保证安全
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);}//正确的结果应该是70System.Console.WriteLine($"main: list size:{mylist.Count}"); }t.Wait();
}
线程安全的队列
/// <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);}//正确的结果应该是70System.Console.WriteLine($"main: list size:{mylist.Count}"); t.Wait();//取出数据//mylist.TryDequeue(out int a);}
线程安全的无序列表
/// <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);}//正确的结果应该是70System.Console.WriteLine($"main: list size:{mylist.Count}"); t.Wait();//取出数据//mylist.TryTake(out int a);}