c# - C# '??' 运算符线程安全吗?

标签 c# .net thread-safety null-coalescing-operator

大家都知道这不是线程安全的:

public StringBuilder Builder
{
    get 
    {
        if (_builder != null)
            _builder = new StringBuilder();
        return _builder; 
    }
}

这个呢?

public StringBuilder Builder
{
    get { return _builder ?? (_builder = new StringBuilder()); }
}

最佳答案

开始编辑

根据您编辑的标题,空合并运算符本身似乎是线程安全的(参见 Phil Haack's analysis )。然而,它似乎并不能保证不会对 StringBuilder 构造函数进行潜在的多次调用。

结束编辑

线程有一个更大的问题,那就是 Builder 属性本身表示可以跨线程共享的状态。即使您使惰性初始化线程安全,也不能保证使用 Builder 的方法以线程安全的方式进行。

// below code makes the getter thread safe
private object builderConstructionSynch = new object();
public StringBuilder Builder
{
    get
    {
        lock (builderConstructionSynch)
        {
            if (_builder == null) _builder = new StringBuilder();
        }
        return _builder;
    }
}

以上将防止 _builder 的惰性初始化中的线程问题,但除非您将调用同步到 StringBuilder 的实例方法,否则无法保证使用 Builder 属性的任何方法的线程安全。这是因为 StringBuilder 中的实例方法并非设计为线程安全的。请参阅 MSDN StringBuilder page 中的以下文本.

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

如果您在多个线程中使用 StringBuilder,最好将其封装在您的类中。将 Builder 设为私有(private)并将您需要的行为公开为公共(public)方法:

public void AppendString(string toAppend)
{
    lock (Builder)
    {
        Builder.Append(toAppend);
    }
}

这样您就不会到处编写同步代码。

关于c# - C# '??' 运算符线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/944683/

相关文章:

objective-c - KVO 和更改 UI 值更改

c# - 检查对象数组的唯一性

c# - 如何在单声道中引用 HttpClient?

c# - StringReader 省略尾随换行符

asp.net - 单页应用程序和 Web 应用程序之间的区别。

c++ - 静态对象的同步

C#:在 GPU 上执行操作,而不是 CPU(计算 Pi)

c# - 每 30 秒重复一次 ping

c# - 如何在 VS 2010 中为 XAML 设计器初始化类?

Spring和Tika集成: is my approach thread-safe?