Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以下C代码在多线程环境中是否是线程安全的?_C#_Multithreading - Fatal编程技术网

C# 以下C代码在多线程环境中是否是线程安全的?

C# 以下C代码在多线程环境中是否是线程安全的?,c#,multithreading,C#,Multithreading,由于我在有人使用该类时立即创建只读静态实例,因此没有延迟加载,该代码是线程安全的,我不需要遵循设计模式,对吗 public class BusSingleton<T> where T : IEmpireEndpointConfig, new() { private static readonly BusSingleton<T> instance = new BusSingleton<T>(); private IBus bus; p

由于我在有人使用该类时立即创建只读静态实例,因此没有延迟加载,该代码是线程安全的,我不需要遵循设计模式,对吗

public class BusSingleton<T> where T : IEmpireEndpointConfig, new()
{

    private static readonly BusSingleton<T> instance = new BusSingleton<T>();
    private IBus bus;

    public IBus Bus
    {
        get { return this.bus; }
    }

    public static BusSingleton<T> Instance
    {
        get
        {
            return instance;
        }
    }

    private BusSingleton()
    {
        T config = new T();
        bus = NServiceBus.Bus.Create(config.CreateConfiguration());
        ((IStartableBus) bus).Start();
    }
}
公共类BusSingleton,其中T:IEMPirendPointConfig,new() { 私有静态只读BusSingleton实例=新BusSingleton(); 私人IBus巴士; 公共IBus巴士 { 获取{返回this.bus;} } 公共静态总线单实例 { 得到 { 返回实例; } } 私人巴士单身人士() { T config=newt(); bus=NServiceBus.bus.Create(config.CreateConfiguration()); ((IStartableBus)总线).Start(); } }
这看起来很安全,只要不需要延迟实例化来运行初始化代码或类似的东西。听起来你不需要。

在静态初始值设定过程中,运行时会在对象的类型周围放置一个锁,因此不能同时运行初始值设定的两个实例

唯一需要注意的是,如果
NServiceBus.Bus.Create
config.CreateConfiguration
Bus.Start()
在内部使用多个线程,并尝试访问其他线程上类/函数中的任何位置的对象类型。如果这三个函数调用中的一个直到内部线程完成后才返回,则可能会导致自己死锁

当您使用双重检查锁定执行传统的“惰性单例”时,静态初始值设定项将已经完成,并且您不会自行承担死锁的风险


因此,如果您确信这3个函数不会尝试在另一个线程上访问您的类型,那么不在您的用例中使用双重检查锁定是可以的。

我不同意重复的建议。副本仅显示了如何执行双重检查锁定。这是在询问“在这种特定情况下是否需要双重检查锁定?”静态初始值设定项锁定是否适用于
T
的所有值,还是仅适用于每个值?也就是说,如果线程A执行
BusSingleton
,线程B执行
BusSingleton
,那么
BusSingleton
的类型初始值设定项能否针对每种类型的T、
Bar
Foo
并行运行?如果它是这样工作的,那么实例构造函数将并行运行,因此
Create
Start
也需要是线程安全的。是的,它们可以并行运行,在处理静态和泛型时,就在您的脑海中,将
替换为
。现在再问一次你的问题“如果一个线程在做
busingleton\u Foo\u
,另一个线程在做
busingleton\u Bar\u
-类型初始化器可以为Bar和Foo并行运行吗?”答案是“当然可以,它们是两种不同的类型”@vcsjones我同意
Create
必须是线程安全的,但是假设
Create
创建了
IStartableBus
对象的新实例,那么
Start
不需要是线程安全的,因为它是函数的本地实例。同意-但我不知道NServiceBus做了什么。据我所知,
Start
在它的实现中访问/使用一些共享静态数据(假设)。因此,其安全性完全取决于NServiceBus的API。