R# - 可能错误地实现Double-Check锁定模式

时间:2016-09-26 12:00:38

标签: c# multithreading resharper

private readonly Object _syncRoot = new Object();
public IdGenerator ClientIdGenerator
{
    get
    {
        if ( clientIdGenerator != null )
            return clientIdGenerator;

        lock ( _syncRoot )
        {
            if ( clientIdGenerator != null )
                return clientIdGenerator;

            return clientIdGenerator = ClientIdPrefix != null ? new IdGenerator( ClientIdPrefix ) : new IdGenerator();
        }
    }
}

R#在创建IdGenerator实例的行上显示警告“可能不正确实现双重检查锁定模式。对已检查字段的读取权限”。

将代码更改为此后,R#不显示警告:

public IdGenerator ClientIdGenerator
{
    get
    {
        if ( clientIdGenerator == null )
            lock ( _syncRoot )
            {
                if ( clientIdGenerator != null )
                    return clientIdGenerator;

                clientIdGenerator = ClientIdPrefix != null ? new IdGenerator( ClientIdPrefix ) : new IdGenerator();
            }
        return clientIdGenerator;
    }
}

第一个例子有什么问题,或者R#是否显示“错误”警告?

1 个答案:

答案 0 :(得分:1)

您的第一个版本应该可以很好地工作,但为了避免对部分代码分析引擎或同事的误解,您可以使用标准模式:

private readonly Object _syncRoot = new Object();
public IdGenerator ClientIdGenerator
{
    get
    {
        if (clientIdGenerator == null)
        {
            lock (_syncRoot)
            {
                if (clientIdGenerator == null)
                {
                    clientIdGenerator = ClientIdPrefix != null ? new IdGenerator(ClientIdPrefix) : new IdGenerator();
                }
            }
        }

        return clientIdGenerator;
    }
}

通过这种方式,您可以明确自己的意图。