若是在線程之間共享數據,則可能會出現線程爭用的問題c#
1,局一個線程爭用的例子:安全
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace ConsoleApplication6 { class Program { static void Main(string[] args) { SampleTask st = new SampleTask(); StateObject so = new StateObject(); //開啓20個任務,每一個任務循環執行StateObject類的ChangeState方法 for (int i = 0; i < 20; i++) { new Task(st.RaceCondition, so).Start(); } Console.WriteLine("運行完成"); Console.ReadLine(); } } //簡單的任務類 class SampleTask { public void RaceCondition(object o) { Trace.Assert(o is StateObject, "只能傳遞StateObject對象"); StateObject s = o as StateObject; int i = 0; //單個任務循環執行StateObject類的ChangeState方法 while (true) { s.ChangeState(++i); } } } //狀態類 //若是state爲5,則加1,後面跟着檢查state,若是不爲6,就出現了爭用。 class StateObject { int state = 5; public void ChangeState(int loop) { if (state == 5) { state++; //爲false說明出現爭用,則程序斷言(彈出框) Trace.Assert(state == 6, "在循環了" + loop.ToString() + "次後出現了爭用"); } state = 5; } } }
2,解決辦法:ide
①:使用lock鎖定共享的s變量oop
//簡單的任務類 class SampleTask { public void RaceCondition(object o) { Trace.Assert(o is StateObject, "只能傳遞StateObject對象"); StateObject s = o as StateObject; int i = 0; //單個任務循環執行StateObject類的ChangeState方法 while (true) { //使用lock鎖定共享的s變量 lock (s) { s.ChangeState(++i); } } } }
②:將共享對象設置爲線程安全的對象this
//狀態類 //若是state爲5,則加1,後面跟着檢查state,若是不爲6,就出現了爭用。 class StateObject { int state = 5; public void ChangeState(int loop) { //將共享對象設置爲線程安全的對象 lock (this) { if (state == 5) { state++; //爲false說明出現爭用,則程序斷言(彈出框) Trace.Assert(state == 6, "在循環了" + loop.ToString() + "次後出現了爭用"); } state = 5; } } }