Зачем использовать StringBuilder? StringBuffer может работать с несколькими потоками, а также с одним потоком? - PullRequest
16 голосов
/ 30 мая 2011

Предположим, что наше приложение имеет только один поток.и мы используем StringBuffer тогда в чем проблема?

Я имею в виду, если StringBuffer может обрабатывать несколько потоков через синхронизацию, в чем проблема для работы с одним потоком?

Зачем использоватьStringBuilder вместо?

Ответы [ 8 ]

27 голосов
/ 30 мая 2011

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

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

Итак, предпочитайте StringBuilder, потому что,

  • Небольшой прирост производительности.
  • StringBuilder является заменой 1: 1 для класса StringBuffer.
  • StringBuilder не синхронизирован с потоками и поэтому работает лучше в большинстве реализаций Java

Проверьте это:

7 голосов
/ 30 мая 2011

StringBuilder должен быть (крошечным) немного быстрее, потому что он не синхронизирован (потокобезопасен).

Вы можете заметить разницу в действительно тяжелых приложениях.

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

http://download.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html

5 голосов
/ 30 мая 2011

Использование 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.

3 голосов
/ 30 мая 2011

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

. Единственное отличие состоит в крошечных накладных расходах, добавляемых за счет синхронизации всех методов, что не дает никаких преимуществ в однопоточном приложении.

Мое мнениеявляется то, что main причина StringBuilder была введена в том, что компилятор использует StringBuffer (и теперь StringBuilder), когда он компилирует код, содержащий String конкатенацию: в этих случаях синхронизация не требуется и замена всех этих мест несинхронизированными StringBuilder может обеспечить небольшое улучшение производительности.

2 голосов
/ 30 мая 2011

StringBuilder имеет лучшую производительность, потому что его методы не синхронизированы.

Так что, если вам не нужно создавать строку одновременно (что в любом случае является довольно нетипичным сценарием), то нет необходимости «платить» за ненужные накладные расходы на синхронизацию.

0 голосов
/ 10 июня 2017

Существует огромная стоимость для синхронизации объектов.Не рассматривайте программу как отдельную сущность;Это не проблема, когда вы читаете концепции и применяете их в небольших программах, которые вы упомянули в деталях вашего вопроса, проблемы возникают, когда мы хотим масштабировать систему.В этом случае ваша однопоточная программа может зависеть от нескольких других методов / программ / сущностей, поэтому синхронизированные объекты могут вызвать серьезную сложность программирования с точки зрения производительности.Поэтому, если вы уверены, что синхронизировать объект не нужно, вам следует использовать StringBuilder, так как это хорошая практика программирования.В конце мы хотим научиться программировать, чтобы создавать масштабируемые высокопроизводительные системы, и это то, что мы должны делать!

0 голосов
/ 05 июня 2013

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

0 голосов
/ 17 февраля 2013

Это поможет вам, ребята, 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   -> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...