首页 > 解决方案 > 将锁定防止通过反射完成的更改

问题描述

假设一个SomeClass具有这样的private static字段的类。使用 同步访问此字段lock

private static SomeClass _instance
private static object _sync = new object();

public static SomeClass Instance 
{
    get 
    {
        lock (_sync)
        {
            if (_instance == null)
            {
                _instance = Create();
            }
            return _instance;   
        }
    }
}

当来自不同线程的另一个代码将尝试将此变量的值设置为例如null使用反射时,是否会lock阻止这种情况并让反射调用等到锁被释放?

例如这样的:

Type type = typeof(SomeClass);
string fieldName = "_instance";
object value = null;
FieldInfo field = type.GetField(fieldName, true);
field.SetValue(null, value);

标签: c#reflectionlocking

解决方案


不,锁定不会阻止任何不通过锁定同一资源的访问。由于反射不会通过lock,您将获得竞争条件。这是(与您的代码略有不同,但做同样的事情)我的意思→</p>

void SetOne(){
    lock (_sync){
         critical_element = SOME_VALUE;
     }
}

void SetTwo(){
   critical_element = SOME_ANOTHER_VALUE;
}

以上肯定有比赛条件。

这是我对OP问题的理解。我认为 OP 想要使用Singleton模式,这是一个非常好的和线程安全的实现。您也不需要处理锁。但是,一些不良用户可能仍然使用反射设置支持字段。

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy = new Lazy<Singleton>(() => new Singleton());

    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton(){}
}

推荐阅读