@Pop Catalin: 我对你在以下内容说的话感到不满意:
如果结构体旨在实现线程安全,则应仅使方法成为实例方法,仅当它们执行原子操作时,否则应选择静态方法。
这是一个小程序,演示了静态方法不能解决结构体中的问题:
using System;
using System.Threading;
using System.Diagnostics;
namespace ThreadTest
{
class Program
{
struct SmallMatrix
{
double m_a, m_b, m_c, m_d;
public SmallMatrix(double x)
{
m_a = x;
m_b = x;
m_c = x;
m_d = x;
}
public static bool SameValueEverywhere(SmallMatrix m)
{
return (m.m_a == m.m_b)
&& (m.m_a == m.m_c)
&& (m.m_a == m.m_d);
}
}
static SmallMatrix s_smallMatrix;
static void Watcher()
{
while (true)
Debug.Assert(SmallMatrix.SameValueEverywhere(s_smallMatrix));
}
static void Main(string[] args)
{
(new Thread(Watcher)).Start();
while (true)
{
s_smallMatrix = new SmallMatrix(0);
s_smallMatrix = new SmallMatrix(1);
}
}
}
}
请注意,在普通处理器上,双精度浮点数的这种行为无法观察到,因为大多数x86指令都有一个适用于64位块的版本,例如
movl
。
因此,线程安全似乎不是使IsNaN成为静态的好理由:
1. 框架应该是平台无关的,因此不应预设处理器体系结构之类的东西。IsNaN的线程安全性依赖于目标体系结构上始终以原子方式访问和修改64位值的事实(而Compact框架的目标不是x86…)。
2. IsNaN本身是无用的,并且在多个线程可以访问
someVar
的情况下,此代码无论如何都不安全(无论IsNaN的线程安全性如何)。
print("code sample");
if (!double.IsNaN(someVar))
Console.WriteLine(someVar);
我的意思是,即使IsNaN使用所有可能的NaN值进行==
比较实现...(不太可能)......如果方法在执行期间值发生变化,那么谁会在乎,反正方法终止时它可能已经改变了...或者它甚至可能是一个中间值,如果目标体系结构不是x86,则永远不应该出现这种情况...
通常情况下,在两个不同的线程中访问内置值是不安全的,因此,在处理结构体或任何其他类型时,我认为没有提供任何静态方法的虚假安全性 illusion有任何意义。