繁体   English   中英

使用volatile关键字和lock语句

[英]Using volatile keyword and a lock statement

我在应用程序中得到“对volatile字段的引用不会被视为volatile”警告。 我理解为什么。

作为一个简单的例子,即使我仍然会收到警告,下面的代码会使问题线程安全吗?

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
}

锁定会强制两侧的内存屏障,所以是的,您的示例是线程安全的。

你几乎自己回答:

ChangeValue(ref myVal); //Warning here
ChangeValue(ref myNonVolatileNumber); //no warning

编译的ChangeValue()只有一个副本,里面的代码应该实现'volatile'行为。 但是编译器(Jitter)在编译时无法预测所有调用。 唯一的选择是将每个 ref参数视为volatile,这将是非常低效的。

但是看看@ Steven的评论, volatile和无用一样好,应该避免。

可能不需要在您使用过的地方使用volatile关键字。

这个SO问题回答了所有应该使用volatile关键字的地方:

什么时候应该在C#中使用volatile关键字?

会有什么问题

private int val = 10;
private var valLock = new object();
private int nonVolatileNumber = 50;
private var nonVolatileNumberLock = new object();

public int Value
{
    get { lock(valLock) return val; }
    set { lock(valLock) val = value; }
}

public int NonVolatileNumber
{
    get { lock(nonVolatileNumberLock) return nonVolatileNumber; }
    set { lock(nonVolatileNumberLock) nonVolatileNumber = value; }
}

,这里唯一的风险是后续代码访问属性的私有成员。

在32位整数的情况下,甚至64位系统上的64位整数,因为读取将是原子的,你可以像这样使用Interlocked类......

private int val = 10;

public int Value
{
    get { return val; }
    set { Interlocked.Exchange(ref val, value); }
}

或者在更复杂的类型的情况下,您可以使用ReadWriterLockSlim ...

private SomeStructure complex;
private var complexLock = new ReadWriterLockSlim();

public SomeStructure Complex
{
    get
    {
        complexLock.EnterReadLock();
        try
        {
            return complex;
        }
        finally
        {
            complexLock.ExitReadlock();
        }
    }
    set
    {
        complexLock.EnterWriteLock();
        try
        {
            return complex;
        }
        finally
        {
            complexLock.ExitWritelock();
        }
    }
}

这比标准锁更好,因为它允许多个同时读取。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM