我有一段时间的混乱,静态方法实现线程安全,实例方法肯定是线程安全的,如果我们为每个线程分配一个单独的实例,那么它们不会插入,那么我已经意识到,线程安全更多关于类型然后是方法,它们本身不是内存分配,所以让我们举一个例子:
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的多个线程访问时,两种方法之间没有区别。我已经测试了相同但想验证我的理解是否正确。
答案 0 :(得分:2)
线程安全与类和类实例无关。两者都可以以不安全的方式用于线程化。
但是,像winforms控件这样的对象无法从其他线程访问它们的资源,因此它们会检查你是否从其他线程访问它们,并且你必须确保使用Invoke来为该控件使用所需的线程...
答案 1 :(得分:2)
静态方法实现线程安全吗?
不,如果他们修改共享数据,那么它们就像非线程安全一样。您的示例可能没问题但只是因为共享数据本身就是线程安全的ConcurrentDictionary
不可变类型(int
s)。
如果我们为每个线程分配一个单独的实例,实例方法肯定是线程安全的
嗯不,如果一个实例被一个线程访问,那么它就不会使它成为线程安全的。这只是避免了多线程问题。
简而言之,static
与多线程无关。
答案 2 :(得分:2)
静态方法不是线程安全的,因为它们是静态的。
它们是线程安全的,因为有人让它们成为线程安全的。通常在.NET框架中,静态方法是线程安全的,因为有人以那种方式编写。
你可以轻松编写非线程安全的静态成员,这里没有任何魔法。
必须遵循编写线程安全实例成员必须遵循的完全相同的规则来编写线程安全的静态成员。
答案 3 :(得分:1)
instance methods are certainly thread safe, if we assign a separate instance to each thread
是的,当一个线程构造一个对象时,只有这个线程有一个对该对象的引用,没有其他线程可以访问该对象,并且在调用实例方法时不需要线程同步。
线程安全并不意味着同步
线程安全意味着如果两个线程在某个时间尝试访问数据,数据不会被破坏。线程安全还取决于您正在读取的类型和写入适合单个数据的数据类型word(在32位处理器上为int,在64位处理器上为long)是线程安全的。
同步它是一种实现线程安全的方法,但也是对象的不变性。
回到你的问题,例如,如果你的线程通过静态字段公开对象的引用并将其作为状态参数传递给另一个线程的方法,那么如果线程可以尝试同时写入访问,则需要同步(但不是只读的,与读写访问不同)
因此,在读取和写入的同时,许多线程可以访问的对象(与方法无关)(静态或实例)应该是线程安全的。