锁的正确使用位置在哪里
我尝试在多线程环境中找到最好的相似性。
有没有更好的替代方案或者下面两个版本相同?
// float bestSimilarity is shared
// float _similarity is local
lock(locker)
if (_similarity > bestSimilarity)
bestSimilarity = _similarity;
与
if (_similarity > bestSimilarity)
lock(locker)
bestSimilarity = _similarity;
I try to find the best similarity in multithreaded environment.
Is there any better alternative or both versions are same below?
// float bestSimilarity is shared
// float _similarity is local
lock(locker)
if (_similarity > bestSimilarity)
bestSimilarity = _similarity;
vs
if (_similarity > bestSimilarity)
lock(locker)
bestSimilarity = _similarity;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您的第一个案例将有保证。然而,第二种情况可能会失败。您进行比较,然后请求锁定,同时另一个线程已经修改了 bestSimilarity,而您却不知道它使比较无效。
如果你想避免直到最后一刻才被锁定,你可以进行两次比较。也就是说,比较,获取锁,再次比较,只有当它仍然有效时,才增加该值。但要小心您要比较的值的本地缓存。如果你想做到这一点,你需要有某种同步,比如 MemoryBarrier。这一切可能会变得非常复杂,所以我建议锁定整个事情,除非您注意到性能确实是一个瓶颈
Your first case will work guaranteed. The second case however might break down. You compare, then request a lock while in the meantime another thread already modifies bestSimilarity without you knowing of it making the comparison invalid.
If you want to avoid the lock untill the last minute, you can do a comparison twice. That is, compare, acquire a lock, compare again and only if its still valid, increase the value. Be carefull though with local cache of the value you're comparing against. If you want to do this, you need to have some kind of synchronization there like a MemoryBarrier. This all can get pretty complex so i recommend just lock the whole thing unless you notice performance really is a bottleneck
由于
bestSimilarity
是共享的,因此您需要使用第一个代码段As
bestSimilarity
is shared, you will need to use the first code segment第二个不是线程安全的,在执行 if 测试后另一个线程可能会更改
_similarity
。The second is not thread safe, another thread could change
_similarity
after the if test has been performed.第一个解决方案是线程安全的,第二个则不是。
但是,您可以使用双重检查锁来减少获取锁的开销
The first solutions is thread safe - the second is not.
However you can use double-checked lock to reduce the overhead of acquiring a lock
您也可以无锁地执行此操作:
这:
bestSimilarity
的快照(我假设是累加器),_similarity
) 到快照(这是稳定的,作为本地)这是完全线程安全的,并且是无锁的
You could also do it lock-free:
This:
bestSimilarity
at the start (which I assume is the accumulator)_similarity
) to the snapshot (which is stable, as a local)This is fully thread-safe, and lock-free