Is.NET';StringBuilder线程安全
Is.NET';StringBuilder线程安全,.net,thread-safety,stringbuilder,.net,Thread Safety,Stringbuilder,StringBuilder的MSDN文档的常规“线程安全”部分说明: …不保证任何实例成员是线程安全的 但这条语句感觉像是对框架中几乎每个类都进行了复制和粘贴: 然而,Gavin Pugh的这些博客文章提到了StringBuilder的线程安全行为: 此外,Reflector披露了StringBuilder的来源以及附带的注释 在SSCLI源代码中,还建议了许多实现注意事项,以确保线程安全: 是否有人更了解在多个并发线程之间共享一个StringBuilder实例是否安全?本文档的全部目的
StringBuilder
的MSDN文档的常规“线程安全”部分说明:
…不保证任何实例成员是线程安全的
但这条语句感觉像是对框架中几乎每个类都进行了复制和粘贴:
然而,Gavin Pugh的这些博客文章提到了StringBuilder的线程安全行为:
此外,Reflector披露了StringBuilder的来源以及附带的注释
在SSCLI源代码中,还建议了许多实现注意事项,以确保线程安全:
是否有人更了解在多个并发线程之间共享一个StringBuilder
实例是否安全?本文档的全部目的是为您提供保证。在这种情况下,对于实例成员,没有任何东西可以保证线程安全,您应该将其视为线程安全,因此依赖于外部同步方法
有些东西可能是线程安全的,这是一个实现细节,它可以而且可能确实从一个版本的框架更改到下一个版本,或者从一个实现更改到下一个版本(事实上,在框架版本中有很多这样的细节在更改;Eric Lippert有一些文章详细介绍了其中的一些细节)。不要依赖它
(换句话说:不要向实现编写代码,而是根据接口和契约编写代码,在本例中,接口和契约是类及其文档的元数据。)绝对不是;下面是一个通过reflector从4.0升级的简单示例:
[SecuritySafeCritical]
public StringBuilder Append(char value)
{
if (this.m_ChunkLength < this.m_ChunkChars.Length)
{
this.m_ChunkChars[this.m_ChunkLength++] = value;
}
else
{
this.Append(value, 1);
}
return this;
}
从:
此类型的任何公共静态(在Visual Basic中共享)成员都是
线程安全。不保证任何实例成员都是线程
安全的
String.Builder
直到3.5版本仍然包含线程检查代码。有关更多详细信息,请参阅。
var gate = new ManualResetEvent(false);
var allDone = new AutoResetEvent(false);
int counter = 0;
var sb = new StringBuilder();
ThreadStart work = delegate
{
// open gate when all 5 threads are running
if (Interlocked.Increment(ref counter) == 5) gate.Set();
else gate.WaitOne();
for (int i = 0; i < 1000; i++) sb.Append("a");
if (Interlocked.Decrement(ref counter) == 0) allDone.Set();
};
for(int i = 0 ; i < 5 ; i++)
{
new Thread(work).Start();
}
allDone.WaitOne();
Console.WriteLine(sb.Length);