如果在线程之间共享数据,则可能会出现线程争用的问题
成都网络公司-成都网站建设公司创新互联10余年经验成就非凡,专业从事网站设计、成都做网站,成都网页设计,成都网页制作,软文发布平台,广告投放等。10余年来已成功提供全面的成都网站建设方案,打造行业特色的成都网站建设案例,建站热线:18982081108,我们期待您的来电!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,解决办法:
①:使用lock锁定共享的s变量
//简单的任务类 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); } } } }
②:将共享对象设置为线程安全的对象
//状态类 //如果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; } } }
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。