我注意到.Net框架文档的大多数地方都有以下声明。
问题:这个秘诀是什么?我不认为静态类总是线程安全的。我的问题涉及.Net框架中提供的标准类,而不是开发人员创建的自定义类。
下面的静态类中的方法'GetString'是否是线程安全的,因为该方法是一个静态方法?
public static class MyClass
{
static int x = 0;
static MyClass()
{
x = 23;
}
public static string GetString()
{
x++;
return x.ToString();
}
}
答案 0 :(得分:9)
你提到的框架方法不是线程安全的,因为它们是静态的,但是因为它们是专门设计的是是线程安全的。线程安全通常很难实现,但它通常是静态方法所必需的,因为它们变异的任何状态都是在线程之间共享的。
您发布的示例方法不是线程安全的,因为它会改变线程之间共享的状态,而不会有任何同步机制。
答案 1 :(得分:2)
使用非线程安全实例方法而没有任何线程问题的最简单方法是让该实例仅对一个线程可见(只是不要在静态或其他线程的其他地方放置引用)它创建它将访问它)。实际上,这种情况发生的时间超过90%而没有任何特别的努力。
第二个最简单的方法是将一个锁对象与实例相关联(无论是将其用作锁对象,还是在同一范围内都有一个字段和锁对象)并确保所有访问锁都正确。 / p>
使用静态方法我们没有这些选项,因为没有这样的实例,任何线程都可能调用它或其他任何时候发生冲突的静态方法。它甚至可能不是来自同一作者的代码。我们也不能保证其他代码使用我们现有的锁定对象来使用它。
因此,非线程安全的静态方法使用非常有限;几乎只适用于非常有限的情况下使用的私有静态方法,这些限制提供了一次只能由一个线程调用的保证。
因此,使用所有公共静态方法,可以确保它们是线程安全的(或者非常清楚地记录它们不是线程安全的,以及做出这种奇怪事情的理由)。
事实上,你会发现很多实例方法都记录为“not threadsafe”。他们被列为“非线程安全”的原因是:
答案 2 :(得分:1)
您所指的具体示例旨在确保线程安全。也就是说,它们允许并发访问而不会出现死锁或竞争条件。
在所有类的所有实例中可能并非如此,因此Microsoft已选择明确说明哪些方法是线程安全的,哪些方法不能避免任何歧义。
请参阅最后一段 - .NET Class Library
.NET Framework中的所有公共静态成员(方法,属性,字段和事件)都支持多线程环境中的并发访问。因此,可以从两个线程同时调用任何.NET Framework静态成员,而不会遇到竞争条件,死锁或崩溃。
对于.NET Framework中的所有类和结构,请查看API参考文档中的“线程安全”部分,以确定它是否是线程安全的。如果要在多线程环境中使用非线程安全的类,则必须使用提供必要同步构造的代码来包装类的实例。