使用 volatile 关键字和 lock 语句
我在应用程序中收到“对易失性字段的引用不会被视为易失性”警告。我明白为什么。
作为一个简单的例子,即使我仍然收到警告,下面的代码是否会使问题线程安全?
private volatile int myVal = 10;
private int myNonVolatileNumber = 50;
private static readonly object lockObject = new object();
private void ChangeValue(ref int Value)
{
lock (lockObject)
{
Value = 0;
}
}
private void MyMethod()
{
ChangeValue(ref myVal); //Warning here
ChangeValue(ref myNonVolatileNumber); //no warning
}
I am getting the "a reference to a volatile field will not be treated as volatile" warning in an application. I understand why.
As a simple example will the below code make the issue thread safe even though I will get the warning still?
private volatile int myVal = 10;
private int myNonVolatileNumber = 50;
private static readonly object lockObject = new object();
private void ChangeValue(ref int Value)
{
lock (lockObject)
{
Value = 0;
}
}
private void MyMethod()
{
ChangeValue(ref myVal); //Warning here
ChangeValue(ref myNonVolatileNumber); //no warning
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
锁定会强制两侧的内存屏障,所以是的,您的示例是线程安全的。
Locking forces memory barriers on both sides, so yes, your example is thread safe.
您几乎自己回答:
编译后的 ChangeValue() 只有 1 个副本,其中的代码应该实现“易失性”行为。但编译器(Jitter)在编译时无法预测所有调用。唯一的选择是将每个 ref 参数视为易失性的,这将是非常低效的。
但请参阅@Steven 的评论,
易失性
毫无用处,应该避免。You almost answer it yourself:
There is only 1 copy of the compiled ChangeValue(), the code inside should implement the 'volatile' behaviour. But the compiler (Jitter) cannot predict all calls when it compiles. The only option would be to treat every ref parameter as volatile, that would be very inefficient.
But see @Steven's comment,
volatile
is as good as useless and should be avoided.可能在您使用过的地方不需要使用 volatile 关键字。
这个问题回答了所有应该使用 volatile 关键字的地方:
什么时候应该在 C# 中使用 volatile 关键字?
Probably there is no need for the usage of the volatile keyword at the place you have used.
This SO Question answers where all should the volatile keyword should be used if at all:
When should the volatile keyword be used in C#?
会有什么问题
,这里唯一的风险是后续代码访问该属性的私有成员。
对于 32 位整数,甚至 64 位系统上的 64 位整数,由于读取是原子的,因此您可以使用 Interlocked 像这样的类...
或者在更复杂的类型的情况下,您可以使用 ReadWriterLockSlim ...
这比标准锁更好,因为它允许多个同时读取。
What would be wrong with
, the only risk here is that subsequent code accesses the property's private member.
In the case of 32bit integers, or even 64bit integers on a 64bit system, becasue the reads wil be atomic, you could use the Interlocked class like this ...
Or in the case of a more complex type you could use ReadWriterLockSlim ...
This is better than a standard lock because it allows multiple simultaneous reads.