c#-Structuremap单例线程安全吗?
作者:互联网
目前我有以下课程:
public class PluginManager
{
private static bool s_initialized;
private static object s_lock = new object();
public static void Initialize() {
if (!s_initialized) {
lock (s_lock) {
if (!s_initialized) {
// initialize
s_initialized = true;
}
}
}
}
}
这里重要的是,在应用程序运行时,Initialize()仅应执行一次.我以为我可以将其重构为单例类,因为这将更线程安全?
public sealed class PluginService
{
static PluginService() { }
private static PluginService _instance = new PluginService();
public static PluginService Instance { get { return _instance; } }
private bool s_initialized;
public void Initialize() {
if (!s_initialized)
{
// initialize
s_initialized = true;
}
}
}
问题一,由于我们只会在同一个实例上工作,因此仍然有必要在这里拥有锁(我已将其删除)吗?
最后,我想使用DI和结构映射来初始化我的服务,因此我进行了如下重构:
public interface IPluginService {
void Initialize();
}
public class NewPluginService : IPluginService
{
private bool s_initialized;
public void Initialize() {
if (!s_initialized) {
// initialize
s_initialized = true;
}
}
}
在我的注册表中:
ForRequestedType<IPluginService>()
.TheDefaultIsConcreteType<NewPluginService>().AsSingletons();
这可以按预期工作(在以下代码中,单子返回true):
var instance1 = ObjectFactory.GetInstance<IPluginService>();
var instance2 = ObjectFactory.GetInstance<IPluginService>();
bool singleton = (instance1 == instance2);
因此,我的下一个问题是结构映射解决方案是否像单例类一样安全.唯一的缺点是,这仍将允许直接实例化NewPluginService(如果不使用结构映射).
非常感谢,
本
解决方法:
我会提出一些建议:
>布尔标志应该是可变的
>将您的单例实例设为只读
>初始化不是线程安全的,无论您只有一个实例是事实…因此都应该同步
public sealded class PluginService
{
static PluginService() { }
//make the instance readonly
private static readonly PluginService _instance = new PluginService();
public static PluginService Instance { get { return _instance; } }
// make the flag volatile
private static volatile bool s_initialized = false;
private static object s_lock = new object();
// you still need to synchronize when you're initializing
public void Initialize() {
lock(s_lock)
{
if (!s_initialized)
{
// initialize
s_initialized = true;
}
}
}
}
结构化映射上没有争用,因此它的线程安全性似乎没有受到损害.
您拥有的单例类不是线程安全的.要记住的主要事情是,单个实例并不能确保单个线程只能访问它.如果有多个线程引用该实例,则该实例及其所持有的数据存在争用.如果存在争用,则应确保线程安全(至少同步).
标签:thread-safety,singleton,structuremap,c 来源: https://codeday.me/bug/20191210/2099746.html