c# - 将锁定防止通过反射完成的更改
问题描述
假设一个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);
解决方案
不,锁定不会阻止任何不通过锁定同一资源的访问。由于反射不会通过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(){}
}
推荐阅读
- python - Python 子进程打印截断的输出
- regex - Jmeter:如何使用 Regx 检索第二行中的值?
- javascript - Facebook Instant Games:卡在加载中
- linux - Linux CMD - 如何测量两个命令的时间?
- javascript - 什么时候不使用 Formik 的 FastField?
- delphi - 如何在对象检查器中将 TCollectionItem 属性编辑器注册为对象列表?
- webstorm - 如何在 WebStorm 2019.3 上隔离终端
- python - 查询以具有最高 x 的字母 x 开头的 x
- github - 将凭据存储在 github 机密中是否安全?
- angular - 如何通过更改 Angular 8 中 html 的下拉菜单来更改 api url?