編集開始
編集したタイトルに基づいて、null 合体演算子自体はスレッドセーフのようです ( Phil Haack の分析を参照)。ただし、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 ページの以下のテキストを参照してください。
この型の public static (Visual Basic では共有) メンバーはすべて、スレッド セーフです。インスタンス メンバーは、スレッド セーフであるとは限りません。
複数のスレッドで StringBuilder を使用している場合は、クラスにカプセル化する方がよいでしょう。Builder をプライベートにし、パブリック メソッドとして必要な動作を公開します。
public void AppendString(string toAppend)
{
lock (Builder)
{
Builder.Append(toAppend);
}
}
こうすれば、あちこちに同期コードを書く必要がなくなります。