Потокобезопасность класса StringBuilder

1
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();

В соответствии с MSDN. любой член экземпляра класса StringBuilder не является потокобезопасным. поэтому я считаю, что это не потокобезопасность. Я прав?

  • 1
    Здесь нет обмена, так что это потокобезопасно.
  • 1
    Если два потока обращаются к вашему Test.GetData() он всегда будет возвращать новый экземпляр каждому вызывающему Test.GetData() . Хотя даже это было бы потокобезопасным. Но вызов любого члена самого StringBuilder может чередоваться несколькими потоками
Показать ещё 7 комментариев
Теги:
multithreading
thread-safety
stringbuilder

2 ответа

7
Лучший ответ

Этот код является потокобезопасным, поскольку экземпляры не разделяются между потоками.

Вы столкнулись бы с проблемой, если бы у вас был один экземпляр, разделенный между несколькими потоками. Затем, если у вас было несколько вызовов метода экземпляра из разных потоков, в том же экземпляре код был бы небезопасным.

  • 0
    Благодарю. Но я не понимаю, что говорит MSDN. msgstr "любой член экземпляра класса String-builder не является потокобезопасным". Так как мы не знаем внутреннюю реализацию класса stringbuiler. скажем, у него есть статический член. тогда это не потокобезопасно. я прав
  • 2
    @FatalError вы смотрите на метод GetData() и, кажется, думаете: когда этот метод выполняется из разных потоков, они обращаются к одному и тому же экземпляру. Но они этого не делают. Каждый раз, когда вы вызываете этот метод, создается новый экземпляр . Поэтому, как объясняет Дэвид, никакие экземпляры StringBuilder не разделяются между потоками.
Показать ещё 9 комментариев
0

Предположим, что у вас есть два потока t0 и t1. Оба используют общий экземпляр StringBuilder sb. Каждый поток выполняет следующие соответствующие методы: T0 T1:

public void T0()
{
    sb.Append("0");
    sb.Append("0");
}

public void T1()
{
    sb.Append("1");
    sb.Append("1");
}

Затем вы можете получить следующий результат на sb.ToString()

0011
0101
0110
1010
1100

Таким образом, любая из приведенных выше комбинаций является разумным результатом для метода ToString при использовании двух потоков, вызывающих несинхронизированную общую переменную. В этом случае общая переменная является экземпляром sb где проблема лежит внутри класса. Внутренний буфер будет заполнен вызовом метода Append в этом экземпляре. Эта переменная буфера является переменной, которая эффективно используется совместно.

Вернемся к вашему вопросу: ваш код является потокобезопасным, если вы не делитесь экземпляром с другими потоками и вызываете методы, такие как общие переменные. Если используется общий доступ, вам необходимо синхронизировать вызовы с ним самостоятельно. Затем рассмотрим реализацию синхронизированной обертки.

  • 0
    Вы также можете получить сбой, или данные могут быть потеряны, потому что MSDN говорит, что «любой экземпляр StringBuilder не является потокобезопасным», поэтому недопустимо вызывать один и тот же экземпляр одновременно из двух потоков.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню