概述: 如果两个或两个以上的线程同时访问相同的对象,或者访问不同步的共享状态.就会出现竞态条件
举例: 如果多个线程同时访问对象StateObject,最后结果会如何呢?
如下代码,StateObject定义共享对象,如果一个线程刚好运行到if(State==10),就被其它线程占用.调度器去运行另一个线程. 第二个线程进入If体,将State值增加,即此时State=11, 第一个线程再次被调用,进入If体,State再次被增加,即State=12.也就是说,只要存在State=12时,就发生竞态条件
入口方法Main:
1 static void Main(string[] args)
2 {
3 StateObject obj = new StateObject();
4 for (int i = 0; i < 1000; i++)
5 {
6 System.Threading.Thread t = new System.Threading.Thread(obj.ChangeState);
7 t.Name = "Thread" + i;
8 t.Start();
9 }
10 Console.WriteLine(obj.GetState.ToString());
11 Console.Read();
12 }
2 {
3 StateObject obj = new StateObject();
4 for (int i = 0; i < 1000; i++)
5 {
6 System.Threading.Thread t = new System.Threading.Thread(obj.ChangeState);
7 t.Name = "Thread" + i;
8 t.Start();
9 }
10 Console.WriteLine(obj.GetState.ToString());
11 Console.Read();
12 }
StateObject类:
1 public class StateObject
2 {
3 private int state = 1;
4 public void ChangeState()
5 {
6 while(true)
7 {
8 if(state == 10)
9 {
10 state++;
11 if (state == 12)
12 {
13 Console.WriteLine(System.Threading.Thread.CurrentThread.Name + " " + state);
14 }
15 }
16 state = 10;
17 }
18 }
19 public int GetState
20 {
21 get { return state; }
22 set { state = value; }
23 }
24 }
2 {
3 private int state = 1;
4 public void ChangeState()
5 {
6 while(true)
7 {
8 if(state == 10)
9 {
10 state++;
11 if (state == 12)
12 {
13 Console.WriteLine(System.Threading.Thread.CurrentThread.Name + " " + state);
14 }
15 }
16 state = 10;
17 }
18 }
19 public int GetState
20 {
21 get { return state; }
22 set { state = value; }
23 }
24 }
运行结果: 用If(State = 12)来判断是否发生竞态条件
Thread1 12
Thread4 12
......
以上测试证明多线程在访问同一个对象时会发生竞态条件的可能, 要解决竞态条件,可以使用锁定共享对象的机制.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统