静态或非静态方法,线程安全是针对类型而非方法

本文关键字:类型 方法 安全 静态方法 线程 静态 | 更新日期: 2023-09-27 18:24:29

我有一段时间有这种困惑,静态方法实现线程安全吗,实例方法当然是线程安全的,如果我们为每个线程分配一个单独的实例,那么它们就不会干预,然后我意识到,线程安全更多的是类型而不是方法,它们本身不是内存分配,所以让我们举一个例子:

private static ConcurrentDictionary<int,int> cd;
public static void Method1(int userid)
{
   // Modify static object cd based on userid key
}
public void Method2(int userid)
{
    // Modify static object cd based on userid key
}

本质上,当多个线程在运行时提供不同的用户id来访问时,两个方法之间没有区别。我也做了同样的测试,但想验证我的理解是否正确。

静态或非静态方法,线程安全是针对类型而非方法

静态方法不是线程安全的,因为它们是静态的。

它们是线程安全的,因为有人让它们线程安全。通常在.NET框架中,静态方法是线程安全的,因为有人用这种方式编写它们

你可以很容易地编写非线程安全的静态成员,这里没有什么魔法。

编写线程安全实例成员必须遵循与编写线程安全静态成员完全相同的规则。

静态方法实现线程安全吗?

不,如果它们修改共享数据,那么它们也是非线程安全的。您的示例可能还可以,但这只是因为共享数据本身是线程安全的,是不可变类型的ConcurrentDictionaryints)。

实例方法当然是线程安全的,如果我们为每个线程分配一个单独的实例

不,如果一个实例是由一个线程访问的,那么这并不意味着它是线程安全的。这只是为了避免多线程问题。

简而言之,static与多线程无关。

线程安全与类和类的实例无关。两者都可能以不安全的方式用于线程。

但是通常像winforms控件这样的对象不能从其他线程访问它们的资源,因此它们会检查您是否从其他线程进行访问,并且您必须确保使用Invoke为该控件使用所需的线程。。。

instance methods are certainly thread safe, if we assign a separate instance to each thread

是的,当一个线程构造一个对象时,只有这个线程有对该对象的引用,其他线程不能访问该对象,并且在调用实例方法时不需要线程同步。

线程安全并不意味着同步

线程安全意味着,如果两个线程同时试图访问数据,则数据不会损坏。线程安全性还取决于读取和写入适合单个字的数据类型(32位处理器上为int,64位处理器上是long)是线程安全的。

同步是实现线程安全的一种方法,但对象的不可更改性也是如此。

回到你的问题,例如,如果你的线程通过静态字段公开对对象的引用,并将其作为状态参数传递给另一个线程的方法,那么如果线程可以尝试同时写入访问(但不是只读访问,这与读写访问不同),则需要同步

因此,拥有一个对象(与方法无关)(静态或实例),可以在读写时被多个线程同时访问,这应该是线程安全的。