所以我们都在MSDN上看到许多可用通用对象的线程通知:
“此类型的公共静态(在Visual Basic中为Shared)成员是线程安全的。不保证所有实例成员都是线程安全的。”
我的问题是,作为实例变量与公共静态相比,它是什么使它不安全?
答案 0 :(得分:15)
这只是一般情况。
通常,静态方法是静态的,因为它们不依赖于它们,也不访问另一个线程也可以访问的任何实例定义的数据。通常,它们(静态方法)使用的唯一变量是声明的变量,并且绑定到实现该方法的类的静态内存,而不是分配给对象的内存 - (为该对象创建的类的实例) 。静态方法不能也不能引用或利用任何此类变量。如果方法使用这种实例数据变量,绑定到特定实例,则它不能是静态的。相反,Instance方法会访问实例的某些数据元素(属性或字段)。
如果,otoh,静态方法访问类的静态属性或字段,它同样是非线程安全的。
比赛可能需要四个条件。
答案 1 :(得分:13)
没有内置使静态与实例差不多(重新线程安全),除了:
实例方法不是这样:
因此,通常情况下,调用者需要管理实例上的线程安全性。
有些例外情况是实例是线程安全的(通常用于与线程密切相关的事情,例如生产者 - 消费者队列) - 但IMO任何非线程安全的静态成员都是错误。
答案 2 :(得分:8)
这是国家的问题。一般使多线程不安全的方法是它们不以线程安全的方式访问共享状态。静态方法通常不访问共享状态,因此不太可能遇到此问题。如果静态/共享方法接触静态数据仍然可能存在竞争条件,但一般静态方法则不然。
答案 3 :(得分:0)
非线程安全方法的问题是对共享资源(如实例变量)的并发访问。如果静态方法仅对私有/本地数据起作用,则它本身就是线程安全的。但是,无法保证静态方法可以做到这一点 - 这必须明确地完成。
因此,对于静态方法是线程安全的,它不能在不使用同步的情况下访问静态成员,它应该在修改之前复制它接收的任何数据作为输入。
答案 4 :(得分:0)
TLDR; "这是否意味着静态方法本质上是线程安全的?答案是不。具有上述注释的类将具有线程安全的静态方法,因为Microsoft工程师以线程安全的方式编写代码,可能通过使用锁或其他线程同步机制" (引自http://odetocode.com/Articles/314.aspx)
更多细节
这是什么?没什么,除了为那个特定类写的代码。
该语句是一个声明,告诉您编写该类的程序员已确保所有静态成员(方法和属性)都是线程安全的(但实例成员尚未这样做)。
已经确保静态是线程安全的,因为静态的,它们很可能会被多个线程调用,所以他们需要额外的工作以确保它没问题。静态方法通常也是无状态函数,这意味着它们通常已经是线程安全的(不需要额外的工作)。
相比之下,例如成员,声明就是他们告诉你他们没有那么小心。
通常,实例将由单个线程创建,并且只能由该线程访问;如果实例永远不会被多个线程访问,那么线程安全性就不是问题,所以程序员并不愿意添加它。
该声明不是关于静态vs实例的任何固有属性的声明;两者都可能不安全,除非你输入特定代码以确保多个线程可以毫无问题地访问它们(或者如果它们本质上已经是线程安全的,例如无状态函数)。
这只是一个声明,编写这些类的程序员已经确保静态成员是安全的,但对于实例成员却没有这样做。