.net之多线程变量访问

zhwl 阅读:33 2024-02-25 17:59:16 评论:0

这个问题一直困扰着我:在多线程/多处理器环境中 - 是否有必要使用显式锁来同步对共享变量的访问?

这是一个场景:我有一个指向共享对象的全局变量。创建对象的实例时,对它的引用被放置在变量中,并可供其他线程/处理器访问。

对象本身是不可变的——一旦创建它就永远不会改变,因为多个线程可以访问它而无需任何额外的同步。

偶尔我需要更新对象。我这样做是在侧面创建对象的新实例,然后在全局变量中放置对新对象的引用。

所以这里的问题是:我可以考虑将引用替换为原子操作。换句话说,变量总是对我的对象有一个有效的引用——旧的还是新的?

请您参考如下方法:

is it necessary to use explicit locks to synchronize access to shared variables?


必要的?不。一个好主意?是的。低锁定技术很难做到正确,而且很少被证明是合理的。请记住,锁在竞争时很慢;如果您的锁被争用,请解决导致它们被争用的问题,而不是寻求低锁解决方案。

The object itself is immutable - once created it never changes, because of this multiple threads can access it without any additional synchronization.


惊人的。

Once in a while I need to update the object. I do it be creating a new instance of the object on the side and then place a reference to the new object in the global variable.

So here is the question: Can I consider replacing the reference to be an atomic operation. In other words does the variable always have a valid reference to my object - either the old one or the new one?


是的。 C# 规范保证对引用的操作是原子的。 然而原子性只是线程安全的一小部分。原子性只是保证每次查看变量时,都会从中获得有效的引用。 它不能保证每次查看变量时都会从中获得当前引用 .也不保证 任何两个线程都以相同的顺序看到相同的变化序列。 也不保证 对两个不同变量的两次原子更新按照它们在每个线程上发生的顺序显示 .原子性几乎不能保证你什么,它可能不能保证你足以让你的程序按照你认为应该的方式工作。
我的建议:如果您可以避免在多个线程上访问此变量,请这样做。如果您无法避免它,请在其周围加锁。只有当您发现出于性能原因锁太慢并且无法消除足够的争用时,您才应该考虑采用危险的低锁技术,例如使变量易变、使用互锁交换等。


标签:多线程
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号