C# StringBuilder类的线程安全性

C# StringBuilder类的线程安全性,c#,multithreading,thread-safety,stringbuilder,C#,Multithreading,Thread Safety,Stringbuilder,根据MSDN。StringBuilder类的任何实例成员都不是线程安全的。 所以我认为这不是线程安全的。我说的对吗?此代码是线程安全的,因为线程之间没有共享实例 如果在多个线程之间共享一个实例,则会遇到问题。然后,如果在同一实例上有来自不同线程的多个实例方法调用,则代码将不安全。此代码是线程安全的,因为线程之间没有共享实例 如果在多个线程之间共享一个实例,则会遇到问题。然后,如果在同一个实例上有来自不同线程的多个实例方法调用,那么代码将不安全。假设您有两个线程t0和t1。两者都使用StringB

根据MSDN。
StringBuilder
类的任何实例成员都不是线程安全的。
所以我认为这不是线程安全的。我说的对吗?

此代码是线程安全的,因为线程之间没有共享实例


如果在多个线程之间共享一个实例,则会遇到问题。然后,如果在同一实例上有来自不同线程的多个实例方法调用,则代码将不安全。

此代码是线程安全的,因为线程之间没有共享实例


如果在多个线程之间共享一个实例,则会遇到问题。然后,如果在同一个实例上有来自不同线程的多个实例方法调用,那么代码将不安全。

假设您有两个线程t0和t1。两者都使用
StringBuilder sb
的共享实例。每个线程运行以下相应的方法
T0
T1

class Test {
    public string GetData() {
        StringBuilder sb = new StringBuilder();
        sb.Append("aassffss");
        sb.Append("bbhhhhh");
        return sb.ToString();
    }
}
// calling from multithreads,as below, 
// from each thread i will create new 
// instance and call method.

Test t = new Test(); 
t.GetData();
然后您可能会在
sb.ToString()上获得以下输出

因此,当使用两个线程调用未同步的共享变量时,
ToString
方法可以考虑上述任何组合。在这种情况下,共享变量是
sb
实例,问题位于类内部。在内部,将通过调用该实例上的
Append
方法来填充一些缓冲区。缓冲区变量是有效共享的变量


回到您的问题:只要您不与其他线程共享实例,也不调用共享变量的方法,那么您的代码就是线程安全的。如果是共享的,您需要自己同步对它的调用。然后考虑实现一个同步包装器。

让我们假设您有两个线程T0和T1。两者都使用

StringBuilder sb
的共享实例。每个线程运行以下相应的方法
T0
T1

class Test {
    public string GetData() {
        StringBuilder sb = new StringBuilder();
        sb.Append("aassffss");
        sb.Append("bbhhhhh");
        return sb.ToString();
    }
}
// calling from multithreads,as below, 
// from each thread i will create new 
// instance and call method.

Test t = new Test(); 
t.GetData();
然后您可能会在
sb.ToString()上获得以下输出

因此,当使用两个线程调用未同步的共享变量时,
ToString
方法可以考虑上述任何组合。在这种情况下,共享变量是
sb
实例,问题位于类内部。在内部,将通过调用该实例上的
Append
方法来填充一些缓冲区。缓冲区变量是有效共享的变量



回到您的问题:只要您不与其他线程共享实例,也不调用共享变量的方法,那么您的代码就是线程安全的。如果是共享的,您需要自己同步对它的调用。然后考虑实现一个同步包装器。

这里没有共享,所以它是线程安全的。如果两个线程访问您的代码>测试。GETDATA()/Cuth>方法将总是向每个调用方返回一个新实例。即使这样也会是线程安全的。但是对
StringBuilder
本身的任何成员的调用可能会被几个线程交错,但我不明白MSDN所说的。“字符串生成器类的任何实例成员都不是线程安全的”。因为我们不知道stringbuiler类的内部实现。假设它有一个静态成员。那么这不是线程安全的。我是吗right@FatalError如果需要,.net framework类的静态成员通常是线程安全的。实例成员不是,因为若您不在线程之间共享变量,则根本不需要额外的线程安全代码。也许这个规则有例外,但我还没有看到它们。@psubsee2003通过我的覆盖来查看您丢失的更改。但我的编辑没有被拒绝,好吧。至少我看不到我以前对这个问题所做的任何更改。这里没有共享,因此它是线程安全的。如果两个线程访问您的
Test。GetData()
方法将始终向每个调用方返回一个新实例。即使这样也会是线程安全的。但是对
StringBuilder
本身的任何成员的调用可能会被几个线程交错,但我不明白MSDN所说的。“字符串生成器类的任何实例成员都不是线程安全的”。因为我们不知道stringbuiler类的内部实现。假设它有一个静态成员。那么这不是线程安全的。我是吗right@FatalError如果需要,.net framework类的静态成员通常是线程安全的。实例成员不是,因为若您不在线程之间共享变量,则根本不需要额外的线程安全代码。也许这个规则有例外,但我还没有看到它们。@psubsee2003通过我的覆盖来查看您丢失的更改。但我的编辑没有被拒绝,好吧。至少我看不到我以前在这个问题上做过任何改变。谢谢。但我不明白MSDN所说的。“字符串生成器类的任何实例成员都不是线程安全的”。因为我们不知道stringbuiler类的内部实现。假设它有一个静态成员。那么这不是线程安全的。我是吗right@FatalError您正在查看
GetData()
方法,并且似乎认为:当从不同线程执行该方法时,它们访问相同的实例。但他们没有。每次调用此方法时,都会创建一个新实例。因此,线程之间不会共享StringBuilder的任何实例,正如David解释的那样。这意味着从不同线程对同一实例调用实例方法是不安全的。@DavidHeffernan抱歉,我可能仍然没有理解您所说的。如果string builder类中有一个静态实例成员,那么该appdomain中只有一个静态成员。因此,它可以在两个线程的两个stringbuilder对象中共享。这使得上述代码不是线程安全的。这里的问题基本上是两个线程修改相同数据时的数据竞争。你熟悉这个问题吗?谢谢。但我不明白MSDN所说的。“字符串生成器类的任何实例成员都不是线程安全的”。既然我们不知道
0011
0101
0110
1010
1100