什么使实例成员线程不安全vs公共静态?

cyb*_*nte 20 .net c# thread-safety

所以我们都在MSDN上看到了许多可用通用对象的Threading通知:

"此类型的公共静态(在Visual Basic中为Shared)成员是线程安全的.任何实例成员都不保证是线程安全的."

我的问题是,作为一个实例变量与公共静态有什么关系使它不安全?

Cha*_*ana 16

这只是一般情况.

通常,静态方法是静态的,因为它们不依赖于它们也不访问另一个线程也可以访问的任何实例定义的数据.通常,它们(静态方法)使用的唯一变量是声明的变量,并且绑定到实现该方法的类的静态内存,而不是分配给对象的内存 - (为该对象创建的类的实例) .静态方法不能也不能引用或利用任何此类变量.如果方法使用这种实例数据变量,绑定到特定实例,则它不能是静态的.相反,Instance方法会访问实例的某些数据元素(属性或字段).

如果,otoh,静态方法访问类的静态属性或字段,它同样是非线程安全的.

比赛可能需要四个条件.

  1. 第一个条件是存在可从多个线程访问的内存位置.通常,这些位置是全局/静态变量,或者是可从全局/静态变量访问的堆内存.
  2. 第二个条件是存在一个属性(通常称为不变量),它与这些共享内存位置相关联,这些位置必须为true或有效,才能使程序正常运行.通常,在更新发生更新之前,属性需要保持为true才能使更新正确.
  3. 第三个条件是在实际更新的某些部分期间不变属性不成立.(在处理的某些部分,它暂时无效或错误).
  4. 竞争发生必须发生的第四个也是最后一个条件是另一个线程在不变量被破坏时访问内存,从而导致不一致或不正确的行为.


Mar*_*ell 14

内置任何内容都不会使静态变得多于或少与实例不同(重新线程安全),除了:

  • 静态方法通常是无状态的"纯函数"方法,使它们自动是线程安全的
  • 对静态成员有一个明确的期望线程安全的(因为你不能真正控制每个线程一次做什么) - 所以预计任何可能使线程安全风险的静态方法成为线程安全的

对于实例方法,情况并非如此:

  • 实例方法通常访问该实例上的状态
  • 除非在文档中明确说明,否则不会期望线程安全

因此,通常期望调用者管理实例上的线程安全性.

有些例外情况是实例是线程安全的(通常用于与线程密切相关的事情,例如生产者 - 消费者队列) - 但IMO任何非线程安全的静态成员都是一个错误.

  • 是; 真正的不变性使得线程安全. (2认同)

Jar*_*Par 8

这是国家的问题.一般使多线程不安全的方法是它们不以线程安全的方式访问共享状态.静态方法通常不访问共享状态,因此不太可能遇到此问题.如果静态/共享方法接触静态数据仍然可能存在竞争条件,但通常静态方法不会.