Race Conditions资源竞争
如果两个或更多的线程通过同一对象并且共享状态不是同步的,一个资源竞争就可能发生。为了说明资源竞争,下面的例子定义了一个StateObject类,该类包含一个int类型字段和ChangeState方法。在ChangeState方法实现里面,这个状态变量根据是否为5来决定更改值;如果是,这个值自增。接下来的语句Trace.Assert将立即执行验证值是否为6。
为5的变量自增加1后,你可能断定这个变量现在是6,但是在这里它并不是重点。例如,如果一个线程执行了if(state ==5 )语句,调度者运行另一个线程,它可能优先占用资源。第二个线程现在走进了if语句体里面,并且由于这个state还是5这个值,state自增1变成6,第一个线程随后又被调度,并且下一次state自增变成7.这个时候就会发生资源竞争。
public class StateObject
{
private int state = 5;
public void ChangeState(int loop)
{
if (state == 5)
{
state++;
Trace.Assert(state == 6, "Race condition occurred after " +
loop + " loops");
}
state = 5;
}
}
你可以为task定义一个的方法。SampleTask类里面的RaceCondition方法获得了一个StateObject作为参数。里面有一个while循环,ChangeState方法被调用。变量i是用来在信息中显示循环次数。
public class SampleTask
{
public void RaceCondition(object o)
{
Trace.Assert(o is StateObject, "o must be of type StateObject");
StateObject state = o as StateObject;
int i = 0;
while (true)
{
state.ChangeState(i++);
}
}
}
在程序的Main方法里面,一个新的StateObject被创建,它被所有的tasks所共享。通过使用Lambda表达式调用RaceConditions方法创建Task对象。主线程等待用户的输入。然而,这里可能因为资源竞争的发生使得在读取用户输入之前程序停止。
static void RaceConditions()
{
var state = new StateObject();
for (int i = 0; i < 2; i++)
{
Task.Run(() => new SampleTask().RaceCondition(state));
}
}
ps:未完,内容是为英文版翻译,非原创,勿喷。无聊中...