Разница между StringBuilder и StringBuffer

1414

В чем основное отличие между StringBuffer и StringBuilder? Существуют ли какие-либо проблемы с производительностью при принятии решения по любому из них?

Теги:
stringbuffer
stringbuilder

32 ответа

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

StringBuffer синхронизируется, StringBuilder нет.

  • 218
    StringBuilder предназначен для замены StringBuffer, где синхронизация не требуется.
  • 89
    и синхронизация практически никогда не требуется. Если кто-то хочет синхронизироваться с StringBuilder, он может просто окружить весь блок кода синхронизированным (sb) {} в экземпляре
Показать ещё 13 комментариев
704

StringBuilder быстрее, чем StringBuffer потому что он не synchronized.

Вот простой тестовый тест:

public class Main {
    public static void main(String[] args) {
        int N = 77777777;
        long t;

        {
            StringBuffer sb = new StringBuffer();
            t = System.currentTimeMillis();
            for (int i = N; i --> 0 ;) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }

        {
            StringBuilder sb = new StringBuilder();
            t = System.currentTimeMillis();
            for (int i = N; i > 0 ; i--) {
                sb.append("");
            }
            System.out.println(System.currentTimeMillis() - t);
        }
    }
}

Прогон теста дает номера 2241 ms для StringBuffer против 753 ms для StringBuilder.

  • 9
    Я изменил строковый литерал на нечто большее: «быстрая коричневая лиса» и получил более интересные результаты. В основном они примерно такие же быстрые. У меня фактически закончилась память, поэтому мне пришлось удалить несколько семерок. Объяснение: синхронизация оптимизирована с помощью горячей точки. В основном вы просто измеряете время, необходимое для этого (и, возможно, еще несколько оптимизаций).
  • 0
    Согласитесь с Альфредо. Добавление к комментарию Jiles, при использовании с одной символьной строкой («A»), соотношение равно 2 x 1 (2 для StringBuffer). используя более 3 символов, и я получил "OutOfMemoryError"! (-Xms512m / -Xmx1024m)
Показать ещё 10 комментариев
240

В принципе, методы StringBuffer синхронизируются, а StringBuilder - нет.

Операции "почти" одинаковы, но использование синхронных методов в одном потоке является излишним.

Это в значительной степени об этом.

Цитата из API-интерфейс StringBuilder:

Этот класс [StringBuilder] предоставляет API, совместимый с StringBuffer, , но без гарантии синхронизации. Этот класс предназначен для использования в качестве замены для StringBuffer в местах, где буфера строк используется одним потоком (как это обычно бывает). По возможности рекомендуется, чтобы этот класс использовался вместо StringBuffer как , он будет быстрее в большинстве реализаций.

Так было сделано, чтобы заменить его.

То же самое произошло с Vector и ArrayList.

  • 0
    Также с Hashtable и HashMap .
144

Но нужно ли получить четкую разницу с помощью примера?

StringBuffer или StringBuilder

Просто используйте StringBuilder, если вы действительно не пытаетесь разделить буфер между потоками. StringBuilder - это несинхронизированный младший брат младшего брата исходного младшего класса StringBuffer. <

StringBuffer вышел первым. Солнце заботится о правильности при любых условиях, поэтому они синхронизировали его, чтобы сделать его потокобезопасным на всякий случай.

StringBuilder пришел позже. Большинство применений StringBuffer были однопоточными и неоправданно оплачивали стоимость синхронизации.

Так как StringBuilder является заменой замены для StringBuffer без синхронизации, не было бы различий между любыми примерами.

Если вы пытаетесь разделить потоки, вы можете использовать StringBuffer, но подумайте, нужна ли более высокая синхронизация, например. возможно, вместо использования StringBuffer, следует синхронизировать методы, которые используют StringBuilder.

  • 9
    Первый хороший ответ !! Дело в том, «если вы не разделяете буфер между потоками»
  • 1
    очень подробный ответ!
75

Сначала давайте посмотрим на сходства: Оба StringBuilder и StringBuffer изменяемы. Это означает, что вы можете изменить их содержимое в том же месте.

Различия: StringBuffer изменен и синхронизирован. Если StringBuilder изменен, но не синхронизирован по умолчанию.

Значение синхронизации (синхронизации): Когда какая-то вещь синхронизирована, несколько потоков могут получить доступ и изменить ее без каких-либо проблем или побочных эффектов. StringBuffer синхронизирован, поэтому вы можете использовать его с несколькими потоками без каких-либо проблем.

Какой из них использовать, когда? StringBuilder: когда вам нужна строка, которая может быть модифицируемой, и только один поток обращается к ней и ее модифицирует. StringBuffer: когда вам нужна строка, которая может быть изменчивой, и несколько потоков обращаются к ней и изменяют ее.

Примечание. Не используйте StringBuffer без необходимости, т.е. не используйте его, если только один поток модифицирует и получает доступ к нему, поскольку он имеет много кода блокировки и разблокировки для синхронизации, которое будет излишне время процессора. Не используйте блокировки, если это не требуется.

  • 2
    Просто хочу отметить, что вызовы метода INDIVIDUAL в StringBuffer являются поточно-ориентированными. Но если у вас несколько строк кода, используйте синхронизированный блок кода, чтобы гарантировать безопасность потоков, с некоторой блокировкой / монитором (как обычно ...). По сути, не просто предполагайте, что использование многопоточной библиотеки сразу гарантирует поточную безопасность в ВАШЕЙ программе!
41

В одиночных потоках StringBuffer значительно медленнее, чем StringBuilder, благодаря оптимизации JVM. И в многопоточности вы не можете безопасно использовать StringBuilder.

Вот мой тест:

public static void main(String[] args) {

    String withString ="";
    long t0 = System.currentTimeMillis();
    for (int i = 0 ; i < 100000; i++){
        withString+="some string";
    }
    System.out.println("strings:" + (System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuffer buf = new StringBuffer();
    for (int i = 0 ; i < 100000; i++){
        buf.append("some string");
    }
    System.out.println("Buffers : "+(System.currentTimeMillis() - t0));

    t0 = System.currentTimeMillis();
    StringBuilder building = new StringBuilder();
    for (int i = 0 ; i < 100000; i++){
        building.append("some string");
    }
    System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}

Результаты:
строки: 319740
Буферы: 23
Builder: 7!

Так что строители быстрее, чем буферы, а WAY быстрее, чем конкатенации строк. Теперь позвольте использовать Исполнитель для нескольких потоков:

public class StringsPerf {

    public static void main(String[] args) {

        ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        //With Buffer
        StringBuffer buffer = new StringBuffer();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(buffer));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Buffer : "+ AppendableRunnable.time);

        //With Builder
        AppendableRunnable.time = 0;
        executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
        StringBuilder builder = new StringBuilder();
        for (int i = 0 ; i < 10; i++){
            executorService.execute(new AppendableRunnable(builder));
        }
        shutdownAndAwaitTermination(executorService);
        System.out.println(" Thread Builder: "+ AppendableRunnable.time);

    }

   static void shutdownAndAwaitTermination(ExecutorService pool) {
        pool.shutdown(); // code reduced from Official Javadoc for Executors
        try {
            if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
                pool.shutdownNow();
                if (!pool.awaitTermination(60, TimeUnit.SECONDS))
                    System.err.println("Pool did not terminate");
            }
        } catch (Exception e) {}
    }
}

class AppendableRunnable<T extends Appendable> implements Runnable {

    static long time = 0;
    T appendable;
    public AppendableRunnable(T appendable){
        this.appendable = appendable;
    }

    @Override
    public void run(){
        long t0 = System.currentTimeMillis();
        for (int j = 0 ; j < 10000 ; j++){
            try {
                appendable.append("some string");
            } catch (IOException e) {}
        }
        time+=(System.currentTimeMillis() - t0);
    }
}

Теперь StringBuffers берут 157 мс для 100000 приложений. Это не тот же тест, но по сравнению с предыдущими 37 мс, вы можете смело предположить, что Добавления StringBuffers медленнее при использовании многопоточности. Причина в том, что JIT/hotspot/compiler/something делает оптимизацию, когда обнаруживает, что нет необходимости проверять блокировки.

Но с StringBuilder у вас есть java.lang.ArrayIndexOutOfBoundsException, потому что параллельный поток пытается добавить что-то там, где он не должен.

Заключение заключается в том, что вам не нужно преследовать StringBuffers. И где у вас есть потоки, подумайте о том, что они делают, прежде чем пытаться получить несколько наносекунд.

  • 4
    Вы забыли сделать "t0 = System.currentTimeMillis ();" перед выполнением теста StringBuilder. Таким образом, показатель, отображаемый для StringBuilder, на самом деле является временем, которое потребовалось для запуска теста stringbuffer AND stringbuilder. Добавьте эту строку, и вы увидите, что StringBuilder работает быстрее примерно в два раза.
  • 0
    Исправлено, спасибо. Очевидно, это меняет вещи.
Показать ещё 4 комментария
37

StringBuilder был введен в Java 1.5, поэтому он не будет работать с более ранними JVM.

Из Javadocs:

Класс StringBuilder предоставляет API, совместимый с StringBuffer, но без гарантии синхронизации. Этот класс предназначен для использования в качестве замены для StringBuffer в местах, где буфера строк используется одним потоком (как это обычно бывает). По возможности рекомендуется, чтобы этот класс использовался в предпочтении StringBuffer, поскольку он будет быстрее в большинстве реализаций.

  • 13
    1.4 находится в конце срока службы, так что вряд ли стоит беспокоиться о pre-1.5.
  • 0
    @ tomHawtin-tackline не обязательно - есть версии для предприятий до версии 1.4, которые большинство из нас использует ежедневно. Также BlackBerry Java основан на 1.4, и это все еще очень актуально.
Показать ещё 1 комментарий
33

Довольно хороший вопрос

Вот различия, я заметил:

StringBuffer: -

StringBuffer is  synchronized
StringBuffer is  thread-safe
StringBuffer is  slow (try to write a sample program and execute it, it will take more time than StringBuilder)

StringBuilder: -

 StringBuilder is not synchronized 
 StringBuilder is not thread-safe
 StringBuilder performance is better than StringBuffer.

Обычная вещь: -

Оба имеют одинаковые методы с одинаковыми сигнатурами. Оба являются изменяемыми.

21

StringBuilder не является потокобезопасным. Буфер String. Подробнее здесь.

EDIT: Что касается производительности, после hotspot, побеждает StringBuilder. Однако для небольших итераций разница в производительности незначительна.

19

StringBuffer

StringBuffer является изменяемым, значит, можно изменить значение объекта. Объект, созданный с помощью StringBuffer, сохраняется в куче. StringBuffer имеет те же методы, что и StringBuilder, но каждый метод в StringBuffer синхронизирован, что StringBuffer является потокобезопасным.

из-за этого он не позволяет двум потокам одновременно обращаться к одному и тому же методу. Каждый метод может быть доступен по одному потоку за раз.

Но для потокобезопасности также есть недостатки, так как производительность StringBuffer попадает из-за свойства потокобезопасности. Таким образом, StringBuilder быстрее, чем StringBuffer при вызове тех же методов для каждого класса.

Значение StringBuffer может быть изменено, это означает, что оно может быть присвоено новому значению. В настоящее время это самый распространенный вопрос интервью, различия между вышеуказанными классами. Буфер String можно преобразовать в строку, используя toString().

StringBuffer demo1 = new StringBuffer("Hello") ;
// The above object stored in heap and its value can be changed .

demo1=new StringBuffer("Bye");
// Above statement is right as it modifies the value which is allowed in the StringBuffer

StringBuilder

StringBuilder такой же, как StringBuffer, то есть он хранит объект в куче, и его также можно изменить. Основное различие между StringBuffer и StringBuilder заключается в том, что StringBuilder также не является потокобезопасным. StringBuilder работает быстро, поскольку он не является потокобезопасным.

StringBuilder demo2= new StringBuilder("Hello");
// The above object too is stored in the heap and its value can be modified

demo2=new StringBuilder("Bye");
// Above statement is right as it modifies the value which is allowed in the StringBuilder

Изображение 1329

Ресурс: String Vs StringBuffer Vs StringBuilder

  • 0
    StringBuilder неизменен, а тип String изменчив
  • 0
    Я не согласен, что Strings и StringBuilders «быстрые», а StringBuffers «очень медленные». Смотрите выше ответы.
19

StringBuilder и StringBuffer почти одинаковы. Разница в том, что StringBuffer синхронизируется, а StringBuilder - нет. Хотя StringBuilder быстрее, чем StringBuffer, разница в производительности очень мала. StringBuilder является заменой SUN StringBuffer. Он просто избегает синхронизации из всех общедоступных методов. Вместо этого их функциональность одинакова.

Пример хорошего использования:

Если ваш текст изменится и будет использоваться несколькими потоками, лучше использовать StringBuffer. Если ваш текст изменится, но будет использоваться одним потоком, используйте StringBuilder.

16

StringBuffer

  • Синхронизированный, следовательно, потокобезопасный
  • потокобезопасность, следовательно медленная  -

StringBuilder

  • Введен в Java 5.0
  • Асинхронный, следовательно быстрый и эффективный
  • Пользователь явно должен синхронизировать его, если хочет
  • Вы можете заменить его StringBuilder без каких-либо других изменений
  • 0
    ПРИМЕЧАНИЕ. Только отдельные операции являются поточно-ориентированными, а несколько операций - нет. например, если вы вызываете append дважды или append и toString не является безопасным.
13

String является неизменным.

StringBuffer является изменяемым и синхронизированным.

StringBuilder также изменен, но не синхронизирован.

  • 0
    плюс 1 за хороший и краткий ответ
  • 0
    Кроме того, StringBuffer блокирует потоки для доступа к этим потокобезопасным данным, поэтому работа идет медленно. StringBuilder не блокирует поток и работает в многопоточном режиме, поэтому работает быстро. String - когда вам не нужно объединять строку, это хороший способ, но когда вам это нужно, используйте StringBuilder ->, потому что String создает каждый раз новый объект в куче, а StringBuilder возвращает один и тот же объект ...
11

javadoc объясняет разницу:

Этот класс предоставляет API, совместимый с StringBuffer, но без гарантии синхронизации. Этот класс предназначен для использования в качестве замены для StringBuffer в местах, где буфера строк используется одним потоком (как это обычно бывает). По возможности рекомендуется, чтобы этот класс использовался в предпочтении StringBuffer, поскольку он будет быстрее в большинстве реализаций.

9

StringBuilder (введенный в Java 5) идентичен StringBuffer, за исключением того, что его методы не синхронизированы. Это означает, что он имеет лучшую производительность, чем последний, но недостатком является то, что он не является потокобезопасным.

Подробнее читайте учебник.

7

StringBuilder намного быстрее, чем StringBuffer, потому что он не синхронизирован.

Здесь вы получили больше информации о стоимости синхронизации

Позвольте программно посмотреть, сколько StringBuilder быстрее, чем StringBuffer

public class Test{  
 public static void main(String[] args){  
    long startTime = System.currentTimeMillis();  
    StringBuffer sb = new StringBuffer("Yasir");  
    for (int i=0; i<10000; i++){  
        sb.append("Shabbir");  
    }  
    System.out.println("Time taken by StringBuffer: " + (System.currentTimeMillis() - startTime) + "ms");  
    startTime = System.currentTimeMillis();  
    StringBuilder sb2 = new StringBuilder("Yasir");  
    for (int i=0; i<10000; i++){  
        sb2.append("Shabbir");  
    }  
    System.out.println("Time taken by StringBuilder: " + (System.currentTimeMillis() - startTime) + "ms");  
}  
}  

аудиовыхода

Время, затраченное на StringBuffer: 16 мс

Время, затраченное на StringBuilder: 0ms

5

Простая программа, иллюстрирующая разницу между StringBuffer и StringBuilder:

/**
 * Run this program a couple of times. We see that the StringBuilder does not
 * give us reliable results because its methods are not thread-safe as compared
 * to StringBuffer.
 * 
 * For example, the single append in StringBuffer is thread-safe, i.e.
 * only one thread can call append() at any time and would finish writing
 * back to memory one at a time. In contrast, the append() in the StringBuilder 
 * class can be called concurrently by many threads, so the final size of the 
 * StringBuilder is sometimes less than expected.
 * 
 */
public class StringBufferVSStringBuilder {

    public static void main(String[] args) throws InterruptedException {

        int n = 10; 

        //*************************String Builder Test*******************************//
        StringBuilder sb = new StringBuilder();
        StringBuilderTest[] builderThreads = new StringBuilderTest[n];
        for (int i = 0; i < n; i++) {
            builderThreads[i] = new StringBuilderTest(sb);
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            builderThreads[i].join();
        }
        System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());

        //*************************String Buffer Test*******************************//

        StringBuffer sb2 = new StringBuffer();
        StringBufferTest[] bufferThreads = new StringBufferTest[n];
        for (int i = 0; i < n; i++) {
            bufferThreads[i] = new StringBufferTest(sb2);
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].start();
        }
        for (int i = 0; i < n; i++) {
            bufferThreads[i].join();
        }
        System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());

    }

}

// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {

    StringBuilder sb;

    public StringBuilderTest (StringBuilder sb) {
        this.sb = sb;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb.append("A");
        }

    }
}


//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {

    StringBuffer sb2;

    public StringBufferTest (StringBuffer sb2) {
        this.sb2 = sb2;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            sb2.append("A");
        }

    }
}
4

String-Builder:

int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.

Стринг-Buffer

StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);  

Рекомендуется использовать StringBuilder по возможности, потому что он быстрее, чем StringBuffer. Однако, если безопасность потока необходима, лучшим вариантом являются объекты StringBuffer.

  • 0
    Если вам нужна безопасность потоков, лучший вариант - использовать StringBuilder, поскольку StringBuffer является поточно-ориентированным для отдельных операций. Для нескольких операций вам нужна явная блокировка.
4

StringBuffer:

  • Multi-Thread
  • Синхронное
  • Медленнее, чем StringBuilder

StringBuilder

  • Однозаходные
  • Не-Синхронное
  • Быстрее, чем когда-либо Строка
  • 2
    Точнее, String c = a + b эквивалентно String c = new StringBuilder().append(a).append(b).toString() , так что это не быстрее. Это только то, что вы создаете новый для каждого строкового назначения, в то время как у вас может быть только один ( String d = a + b; d = d + c; is String d = new StringBuilder().append(a).append(b).toString(); d = new StringBuilder().append(d).append(c).toString(); тогда как StringBuilder sb = new StringBuilder(); sb.append(a).append(b); sb.append(c); String d = sb.toString(); сохранит один экземпляр StringBuilder).
4

StringBuffer

StringBuffer является изменяемым, значит, можно изменить значение объекта. Объект, созданный с помощью StringBuffer, сохраняется в куче. StringBuffer имеет те же методы, что и StringBuilder, но каждый метод в StringBuffer синхронизирован, что StringBuffer является потокобезопасным.

StringBuilder

StringBuilder такой же, как StringBuffer, то есть он хранит объект в куче, и его также можно изменить. Основное отличие между StringBuffer и StringBuilder заключается в том, что StringBuilder не является потокобезопасным. StringBuilder работает быстро, поскольку он не является потокобезопасным.

4

StringBuffer является изменчивым. Он может меняться с точки зрения длины и содержания. StringBuffers являются потокобезопасными, что означает, что у них есть синхронизированные методы для управления доступом, так что только один поток может одновременно получать синхронизируемый код объекта StringBuffer. Таким образом, объекты StringBuffer обычно безопасны для использования в многопоточной среде, где несколько потоков могут пытаться одновременно обращаться к одному объекту StringBuffer.

StringBuilder Класс StringBuilder очень похож на StringBuffer, за исключением того, что его доступ не синхронизирован, так что он не является потокобезопасным. Не будучи синхронизированным, производительность StringBuilder может быть лучше, чем StringBuffer. Таким образом, если вы работаете в однопоточной среде, использование StringBuilder вместо StringBuffer может привести к увеличению производительности. Это также относится к другим ситуациям, таким как локальная переменная StringBuilder (т.е. Переменная внутри метода), где только один поток будет обращаться к объекту StringBuilder.

4

Лучше использовать StringBuilder, поскольку он не синхронизирован и, следовательно, более эффективен. StringBuilder является заменой старого StringBuffer.

  • 3
    Если, конечно, ваше приложение не является многопоточным. :)
  • 3
    @Mark true, но большую часть времени StringBu(ff|ild)er является локальной переменной, используемой только одним потоком.
Показать ещё 2 комментария
4

StringBuffer синхронизируется, но StringBuilder - нет. В результате StringBuilder быстрее, чем StringBuffer.

3

Нет никаких основных различий между StringBuilder и StringBuffer, между ними существует только несколько различий. В StringBuffer методы синхронизируются. Это означает, что в то время на них может работать только один поток. Если есть более одного потока, тогда второй поток должен будет дождаться завершения первого, а третье - дождаться завершения первого и второго и т.д. Это делает процесс очень медленным, и, следовательно, производительность в случае StringBuffer низкая.

С другой стороны, StringBuilder не синхронизирован. Это означает, что одновременно несколько потоков могут работать с одним и тем же объектом StrinBuilder одновременно. Это делает процесс очень быстрым, и, следовательно, производительность StringBuilder высока.

3

Поскольку StringBuffer синхронизируется, ему требуется дополнительное усилие, поэтому на основе перфоранса оно немного медленнее, чем StringBuilder.

3

StringBuffer используется для хранения символьных строк, которые будут изменены (объекты String не могут быть изменены). Он автоматически расширяется по мере необходимости. Связанные классы: String, CharSequence.

StringBuilder был добавлен в Java 5. Он во всех отношениях идентичен StringBuffer, за исключением того, что он не синхронизирован, а это означает, что, если к нему одновременно обращаются несколько потоков, могут возникнуть проблемы. Для однопоточных программ наиболее распространенный случай, позволяющий избежать накладных расходов синхронизации, делает StringBuilder очень немного быстрее.

  • 4
    Однопоточные программы не являются наиболее распространенным случаем в Java, но StringBuilder обычно являются локальными для метода, где они видны только одному потоку.
2

Проверьте внутренности синхронизированного метода добавления StringBuffer и несинхронизированного метода добавления StringBuilder.

StringBuffer:

public StringBuffer(String str) {
    super(str.length() + 16);
    append(str);
}

public synchronized StringBuffer append(Object obj) {
    super.append(String.valueOf(obj));
    return this;
}

public synchronized StringBuffer append(String str) {
    super.append(str);
    return this;
}

StringBuilder:

public StringBuilder(String str) {
    super(str.length() + 16);
    append(str);
}

public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

public StringBuilder append(String str) {
    super.append(str);
    return this;
}

Поскольку append имеет значение synchronized, StringBuffer имеет накладные расходы на производительность по сравнению с StrinbBuilder в многопоточном сценарии. Пока вы не используете буфер обмена между несколькими потоками, используйте StringBuilder, что происходит быстро из-за отсутствия synchronized в методах добавления.

2

Основное отличие: StringBuffer синхронизируется, но StringBuilder не является. Если вам нужно использовать более одного потока, тогда рекомендуется StringBuffer. Но, согласно скорости выполнения StringBuilder, быстрее, чем StringBuffer, потому что он не синхронизирован.

  • 4
    StringBuffer безопасен только для потоков, если вы выполняете только одну операцию над ним. Я бы не рекомендовал использовать его в нескольких потоках, потому что это очень трудно понять правильно.
  • 0
    @PeterLawrey что ты имеешь в виду? :-)
Показать ещё 2 комментария
2

String - неизменяемый объект, который означает, что значение не может быть изменено, если StringBuffer изменен.

StringBuffer синхронизирован, поэтому потокобезопасен, где StringBuilder не подходит и подходит только для однопоточных экземпляров.

  • 1
    просто потому, что StringBuffer имеет синхронизированный код, не обязательно означает, что StringBuffer является потокобезопасным. Рассмотрим следующий пример: StringBuffer testingBuffer = "stackoverflow"; Теперь Thread-1 пытается добавить «1» к testingBuffer, а Thread-2 пытается добавить «2» к testingBuffer. Теперь, даже если метод append () синхронизирован, вы не можете быть уверены, будет ли значением testingBuffer быть «stackoverflow12» или «stackoverflow21». На самом деле Oracle рекомендует использовать stringbuilder поверх stringbuffer. Я надеюсь, что это помогло :)
1

Эта ссылка позволит вам понять понятия не только StringBuilder и StringBuffer, но также их связь и различие с классом String. Это поможет вам понять, когда использовать этот класс. http://www.acquireandinspire.org/2013/01/string-string-builder-string-buffer.html

0

Вот результат тестирования производительности для String vs StringBuffer vs StringBuilder. Наконец, StringBuilder выиграл тест. Ниже приведены тестовый код и результат.

Код:

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

Исполните меня на идеоне

Результат:

100000 итераций для добавления одного текста

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

Итерация 10000 для добавления одного текста

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
0

Каждый метод, присутствующий в StringBuffer, синхронизируется. поэтому в то время только одному потоку разрешено управлять объектом StringBuffer. Увеличивает время ожидания потока и создает проблемы с производительностью для преодоления этой проблемы SUN People включил StringBuilder в версию 1.5.

Ещё вопросы

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