C#多线程方法调用中仅执行一次许可证应用的实现疑问
问题说明
我有一个从运行时加载的程序集中获取的类,通过反射(无参构造函数)在多线程环境(基于Channels)中实例化。每个线程都会创建该类的一个实例,随后调用带多参数的Method()方法。其中一个参数包含插件自身所需的许可证密钥,该密钥仅需被应用一次。
当前实现(双重检查锁)
private static bool _IsLicenceApplied; private readonly static object _IsLicenceAppliedInitializationLock = new object(); public void Method(Keys keys, object data) { if(!_IsLicenceApplied) { lock(_IsLicenceAppliedInitializationLock) { if(!_IsLicenceApplied) { Apply(keys); _IsLicenceApplied = true; } } } // 使用data执行方法剩余逻辑 }
存在的疑问
我查阅了大量Stack Overflow回答、博客文章和文档,但关于以下内容的信息与观点存在冲突:
_IsLicenceApplied是否需要标记为volatile- 是否应使用
Volatile类的方法读写_IsLicenceApplied - 是否应使用
Interlocked类实现相同逻辑 - 是否需要在代码块前后调用
Thread.MemoryBarrier()
替代方案相关疑问
很多资料提到单例模式,并建议用Lazy<T>替代这类代码,但我需要将密钥传入方法并由首次执行处理,认为Lazy<T>无法实现这一点。是否有其他内置类可以满足需求?
编辑记录
- 在调用
Apply()后添加了_IsLicenceApplied = true; - 参考LazyInitializer源码后,提出以下可能方案(该方案是否可行?):
private static bool _IsLicenceApplied; private static object _IsLicenceAppliedInitializationLock = new object(); public void Method(Keys keys, object data) { if(!Volatile.Read(_IsLicenceApplied)) { lock(_IsLicenceAppliedInitializationLock) { if(!Volatile.Read(_IsLicenceApplied)) { Apply(keys); Volatile.Write(ref _IsLicenceApplied, true); } } } // 使用data执行方法剩余逻辑 }
内容的提问来源于stack exchange,提问作者Dan Def
相关产品推荐
相关产品推荐

