使用锁的正确位置在哪里

Nim*_*oud 3 c# multithreading locking thread-safety

我试图在多线程环境中找到最佳相似性.

有没有更好的选择,或者两个版本在下面相同?

 // float bestSimilarity is shared
 // float _similarity is local

 lock(locker) 
     if (_similarity > bestSimilarity)
         bestSimilarity = _similarity;
Run Code Online (Sandbox Code Playgroud)

VS

 if (_similarity > bestSimilarity)
     lock(locker) 
         bestSimilarity = _similarity;
Run Code Online (Sandbox Code Playgroud)

Pol*_*ity 7

你的第一个案例将得到保证.然而,第二种情况可能会破裂.你比较,然后请求锁定,同时另一个线程已经修改bestSimilarity而你不知道它使比较无效.

如果你想在最后一刻避开锁定,你可以进行两次比较.也就是说,比较,获取一个锁,再次进行比较,只有当它仍然有效时才增加该值.请注意使用您正在比较的值的本地缓存.如果你想这样做,你需要像MemoryBarrier一样进行某种同步.这一切都变得非常复杂所以我建议只是锁定整个事情,除非你注意到性能确实是一个瓶颈

  • 双重检查锁定与.NET的当前内存模型一起使用,但这可能会改变,因此更好的方法是使用内存屏障.然而,容易弄错,所以在比较之前采取锁的简单策略似乎更合适,除非此代码存在性能瓶颈. (2认同)
  • @Vlad实际上,这里的双重检查*不一定是安全的,因为OP没有定义什么'bestSimilarity`等****.如果它们是"long"等,则读/写不保证是原子的,因此初始比较可能是比较撕裂的值 (2认同)