Зачем использовать StringBuilder? StringBuffer может работать с несколькими потоками, а также с одним потоком?
Предположим, что наше приложение имеет только один поток. и мы используем StringBuffer
, тогда в чем проблема?
Я имею в виду, если StringBuffer
может обрабатывать несколько потоков через синхронизацию, в чем проблема работы с одним потоком?
Зачем использовать StringBuilder
вместо?
Ответы
Ответ 1
StringBuffers
являются потокобезопасными, что означает, что у них есть синхронизированные методы для управления доступом, так что только один поток может одновременно получать синхронизируемый код объекта StringBuffer. Таким образом, объекты StringBuffer обычно безопасны для использования в многопоточной среде, где несколько потоков могут пытаться одновременно обращаться к одному объекту StringBuffer.
StringBuilder's
доступ не синхронизирован, так что он не является потокобезопасным. Не будучи синхронизированным, производительность StringBuilder может быть лучше, чем StringBuffer. Таким образом, если вы работаете в однопоточной среде, использование StringBuilder вместо StringBuffer может привести к увеличению производительности. Это также относится к другим ситуациям, таким как локальная переменная StringBuilder (т.е. Переменная внутри метода), где только один поток будет обращаться к объекту StringBuilder.
Итак, предпочитаем StringBuilder
, потому что
- Малый прирост производительности.
- StringBuilder - это замена на 1:1 для класса StringBuffer.
- StringBuilder не синхронизирован нитью и поэтому лучше работает в большинстве реализаций Java
Проверьте это:
Ответ 2
StringBuilder должен быть (крошечный) бит быстрее, потому что он не синхронизирован (потокобезопасен).
Вы можете заметить разницу в действительно тяжелых приложениях.
Класс StringBuilder обычно следует использовать в предпочтении этому, поскольку он поддерживает все те же операции, но быстрее, поскольку он не выполняет синхронизацию.
http://download.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html
Ответ 3
Использование StringBuffer в нескольких потоках рядом с бесполезным и на самом деле почти никогда не происходит.
Рассмотрим следующее
Thread1: sb.append(key1).append("=").append(value1);
Thread2: sb.append(key2).append("=").append(value2);
каждое добавление синхронизируется, но поток может опускаться в любую точку, поэтому вы можете иметь любую из следующих комбинаций и более
key1=value1key2=value2
key1key2==value2value1
key2key1=value1=value2
key2=key1=value2value1
Этого можно избежать, синхронизируя всю строку за раз, но это побеждает точку использования StringBuffer вместо StringBuilder.
Даже если у вас правильно синхронизированное представление, это сложнее, чем просто создание локальной копии потока всей строки, например. StringBuilder и строки журнала за один раз для класса, такого как Writer.
Ответ 4
StringBuffer
не является ошибочным в однопоточном приложении. Он будет работать так же хорошо, как StringBuilder
.
Единственное различие заключается в крошечных накладных расходах, добавленных при использовании всех синхронизированных методов, что не дает преимущества в однопоточном приложении.
Мое мнение состоит в том, что основная причина StringBuilder
была введена в том, что компилятор использует StringBuffer
(и теперь StringBuilder
), когда компилирует код, содержащий конкатенацию String
: в этих случаях синхронизация никогда, и замена всех этих мест на несинхронизированный StringBuilder
может обеспечить небольшое улучшение производительности.
Ответ 5
StringBuilder
имеет лучшую производительность, потому что методы не синхронизированы.
Так что, если вам не нужно создавать String одновременно (что в любом случае является довольно нетипичным сценарием), тогда нет необходимости "платить" за ненужные служебные данные синхронизации.
Ответ 6
Это поможет вам, ребята,
Be Straight Builder быстрее Buffer,
public class ConcatPerf {
private static final int ITERATIONS = 100000;
private static final int BUFFSIZE = 16;
private void concatStrAdd() {
System.out.print("concatStrAdd -> ");
long startTime = System.currentTimeMillis();
String concat = new String("");
for (int i = 0; i < ITERATIONS; i++) {
concat += i % 10;
}
//System.out.println("Content: " + concat);
long endTime = System.currentTimeMillis();
System.out.print("length: " + concat.length());
System.out.println(" time: " + (endTime - startTime));
}
private void concatStrBuff() {
System.out.print("concatStrBuff -> ");
long startTime = System.currentTimeMillis();
StringBuffer concat = new StringBuffer(BUFFSIZE);
for (int i = 0; i < ITERATIONS; i++) {
concat.append(i % 10);
}
long endTime = System.currentTimeMillis();
//System.out.println("Content: " + concat);
System.out.print("length: " + concat.length());
System.out.println(" time: " + (endTime - startTime));
}
private void concatStrBuild() {
System.out.print("concatStrBuild -> ");
long startTime = System.currentTimeMillis();
StringBuilder concat = new StringBuilder(BUFFSIZE);
for (int i = 0; i < ITERATIONS; i++) {
concat.append(i % 10);
}
long endTime = System.currentTimeMillis();
// System.out.println("Content: " + concat);
System.out.print("length: " + concat.length());
System.out.println(" time: " + (endTime - startTime));
}
public static void main(String[] args) {
ConcatPerf st = new ConcatPerf();
System.out.println("Iterations: " + ITERATIONS);
System.out.println("Buffer : " + BUFFSIZE);
st.concatStrBuff();
st.concatStrBuild();
st.concatStrAdd();
}
}
Output
run:
Iterations: 100000
Buffer : 16
concatStrBuff -> length: 100000 time: 11
concatStrBuild -> length: 100000 time: 4
concatStrAdd ->
Ответ 7
Маниш, хотя на вашем экземпляре StringBuffer есть только один поток, есть некоторые накладные расходы при приобретении и освобождении блокировки монитора в экземпляре StringBuffer всякий раз, когда вызывается какой-либо из его методов. Следовательно, StringBuilder является предпочтительным выбором в среде с одним потоком.
Ответ 8
Существует огромная стоимость синхронизации объектов. Не видеть программу как отдельную сущность; это не проблема, когда вы читаете концепции и применяете их на небольших программах, как вы упомянули в ваших подробностях вопроса, проблемы возникают, когда мы хотим масштабировать систему. В этом случае ваша однопоточная программа может зависеть от нескольких других методов/программ/сущностей, поэтому синхронизированные объекты могут вызвать серьезную сложность программирования с точки зрения производительности. Поэтому, если вы уверены, что нет необходимости синхронизировать объект, вам следует использовать StringBuilder, так как это хорошая практика программирования. В конце мы хотим научиться программированию для создания масштабируемых высокопроизводительных систем, поэтому это то, что мы должны делать!