Зачем использовать StringBuilder? StringBuffer может работать с несколькими потоками, а также с одним потоком?
предположим, что наше приложение имеет только один поток. и мы используем StringBuffer
тогда в чем проблема?
Я имею в виду, если StringBuffer
может обрабатывать несколько потоков через синхронизацию, в чем проблема работать с одним потоком?
зачем использовать StringBuilder
вместо?
8 ответов
StringBuffers
являются потокобезопасными, что означает, что у них есть синхронизированные методы управления доступом, так что только один поток может получить доступ к синхронизированному коду объекта StringBuffer одновременно. Таким образом, объекты StringBuffer обычно безопасны для использования в многопоточной среде, где несколько потоков могут одновременно пытаться получить доступ к одному и тому же объекту StringBuffer.
StringBuilder's
доступ не синхронизирован, поэтому он не является потокобезопасным. Не будучи синхронизированным, производительность StringBuilder может быть лучше, чем StringBuffer. Таким образом, если вы работаете в однопоточной среде, использование StringBuilder вместо StringBuffer может привести к повышению производительности. Это также верно для других ситуаций, таких как локальная переменная StringBuilder (т. е. переменная в методе), где только один поток будет обращаться к объекту StringBuilder.
Так, предпочитаю StringBuilder
, потому что
- небольшой прирост производительности.
- StringBuilder является заменой 1: 1 для класса StringBuffer.
- StringBuilder не синхронизируется с потоком и поэтому лучше работает в большинстве реализаций Java
зацени вот это :
StringBuilder должен быть (крошечным) немного быстрее, потому что он не синхронизирован (потокобезопасен).
вы можете заметить разницу в очень тяжелых приложений.
класс StringBuilder обычно следует использовать в предпочтении к этому, так как он поддерживает все те же операции, но он быстрее, так как он не выполняет синхронизация.
http://download.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html
использование 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 и log lines одновременно для класса, такого как Writer.
StringBuffer
не неправильно в однопоточном приложении. Он будет работать так же хорошо, как StringBuilder
.
единственная разница-это крошечные накладные расходы, добавленные всеми синхронизированными методами, что не приносит никаких преимуществ в однопоточном приложении.
мое мнение:main причина StringBuilder
было введено то, что компилятор использует StringBuffer
(теперь StringBuilder
) при компиляции кода, содержащего String
конкатенация: в те синхронизация случаев никогда необходимо и заменить все эти места несинхронизированным StringBuilder
может обеспечить небольшое повышение производительности.
StringBuilder
имеет лучшую производительность, потому что его методы не синхронизированы.
поэтому, если вам не нужно создавать строку одновременно (что в любом случае является довольно нетипичным сценарием), тогда нет необходимости "платить" за ненужные накладные расходы синхронизации.
Это поможет вам, ребята, Be Straight Builder быстрее, чем буфер,
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 ->
Маниш, хотя есть только один поток, работающий на вашем экземпляре StringBuffer, есть некоторые накладные расходы при получении и освобождении блокировки монитора на экземпляре StringBuffer при каждом вызове любого из его методов. Следовательно, StringBuilder является предпочтительным выбором в среде с одним потоком.
есть огромная стоимость для синхронизации объектов. Не рассматривайте программу как автономную сущность; это не проблема, когда вы читаете концепции и применяете их к небольшим программам, как вы упомянули в своих деталях вопроса, проблемы возникают, когда мы хотим масштабировать систему. В этом случае ваша однопоточная программа может зависеть от нескольких других методов/программ/сущностей, поэтому синхронизированные объекты могут вызвать серьезную сложность программирования с точки зрения производительности. Так что если вы уверены, что нет необходимости синхронизировать объект, тогда вы должны использовать StringBuilder, поскольку это хорошая практика программирования. В конце мы хотим научиться программировать, чтобы сделать масштабируемые высокопроизводительные системы, так что это то, что мы должны делать!