StringBuilder的MSDN文档中的常规“线程安全”部分指出:
...any实例成员不能保证线程安全.
但是,这个声明似乎已经被复制和粘贴到了框架中的几乎每个类:
http://msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx
然而,Gavin Pugh的这些博客文章提到了StringBuilder的线程安全行为。
http://www.gavpugh.com/2010/03/23/xnac-stringbuilder-to-string-with-no-garbage/
http://www.gavpugh.com/2010/04/01/xnac-avoiding-garbage-when-working-with-stringbuilder/
此外,Reflector揭示的StringBuilder源代码以及SSCLI源代码中的注释也提出了许多实现考虑因素,以确保线程安全:
http://labs.developerfusion.co.uk/SourceViewer/browse.aspx?assembly=SSCLI&namespace=System.Text&type=StringBuilder
是否有人对StringBuilder实例是否安全地在多个并发线程之间共享有更深入的了解?
发布于 2012-01-12 07:27:16
绝对不是;这里有一个简单的示例,它是通过反射器从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;
}该属性只处理调用方,而不是线程安全;这是绝对而不是线程安全。
更新:看看他引用的源代码,这显然不是当前的.NET 4.0代码库(比较几种方法)。也许他说的是一个特定的.NET版本,或者是XNA --但总体上是而不是。4.0 StringBuilder没有的a m_currentThread字段,Gavin的源代码使用该字段;有一个提示(未使用的常量ThreadIDField)表明使用存在,但是.不再。
如果您想要一个直接拒绝--在4.0上运行这个;它很可能会给出错误的长度(我在4k区域看到了一些,在2k区域中有几个--应该正好是5000),但是其他一些Append方法(例如Append(char))更有可能抛出异常,这取决于时间:
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);发布于 2012-01-12 07:18:00
文件的全部目的是给你保证。在这种情况下,在实例成员上,没有任何保证是线程安全的,因此您应该将其视为线程安全,因此依赖于外部同步方法。
有些东西可能是threadsafe,这是一个实现细节,它可以而且可能确实会从框架的一个版本更改到下一个版本,或者从一个实现更改到下一个版本(事实上,在框架版本中有很多这样的细节更改;Eric Lippert有一些文章详细介绍了其中的一些细节)。不要依赖它。
(换句话说:不要为实现编写代码,而是根据接口和契约编写代码,在本例中,接口和契约是类及其文档的元数据。)
发布于 2014-04-15 15:59:40
来自MSDN文档
此类型的任何公共静态(在Visual中共享)成员都是线程安全的。不保证任何实例成员都是线程安全的。
https://stackoverflow.com/questions/8831385
复制相似问题