通过'Instance'访问'Toggle()'类线程安全吗?如果是的话,通过什么假设,规则等等。如果不是,为什么以及如何修复它?
不,它不是线程安全的。
基本上,两个线程可以运行在同一时间的Toggle
功能,所以这可能发生
// thread 1 is running this code
if(value == 0)
{
value = 1;
// RIGHT NOW, thread 2 steps in.
// It sees value as 1, so runs the other branch, and changes it to 0
// This causes your method to return 0 even though you actually want 1
}
else if(value == 1)
{
value = 0;
}
return value;
你需要用下面的假设来操作。
如果2个线程正在运行,他们可以并将在任何点随机交互和交互。您可以通过写入或读取64位整数或浮点数(在32位CPU上)并且另一个线程可以跳入并将其从底下更改为半途。
如果2个线程永远不会访问任何共同的东西,这并不重要,但只要他们这么做,就需要阻止他们踩到彼此的脚趾。在.NET中这样做的方式是使用锁。
你可以决定什么,在哪里被考虑这样的事情锁定:
对于给定的代码块,如果something
的价值得到了超越我改出来的,会很重要?如果是这样,您需要在代码的持续时间内锁定something
。
在您的例子再次
// we read value here
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
// and we return it here
return value;
展望为了使该回什么,我们期待它,我们假设value
不会得到读取和return
之间变化。为了使这个假设实际上正确,您需要在该代码块的持续时间内锁定value
。
所以,你可以这样做:
lock(value)
{
if(value == 0)
... // all your code here
return value;
}
无论其
在.NET中你只能锁定引用类型。 Int32是一个值类型,所以我们不能锁定它。
我们通过引入'虚拟'对象来解决这个问题,并锁定,无论我们想锁定'值'。
这就是Ben Scheirman所指的。
它需要私人ctor真正的单身? – 2015-08-26 13:28:12