Коли я повинен використовувати StringBuilder або StringBuffer?


13

У виробничому веб-додатку мої колеги-програмісти всюди використовували StringBuffer. Тепер я дбаю про розробку та виправлення програм. Прочитавши StringBuilder і StringBuffer, я вирішив замінити весь код StringBuffer на StringBuilder, оскільки нам не потрібна безпека потоку в наших бобах даних.

Наприклад: (У кожному бобі даних я бачу використання StringBuffer)

@Override
public String toString() {
    StringBuffer sb = new StringBuffer();// replace it from StringBuilder
    sb.append(" ABCD : ").append(abcd);
    sb.append(", EFGH : ").append(efgh);
    sb.append(", IJKL : ").append(ijkl);
}

Ми створюємо окремі бази даних для кожного сеансу / запиту. Сеанс використовується одним користувачем, жоден інший користувач не може отримати доступ до нього.

Чи варто розглянути інші моменти перед міграцією?

Якщо є один потік (жодні потоки очікування / жоден новий потік не буде шукати блокування об'єкта), він працює однаково як зі StringBuffer, так і з StringBuilder. Я знаю, що у випадку StringBuffer потрібен час, щоб зняти блокування об'єкта, але я хочу знати, чи є різниця між продуктивністю між ними, крім утримування / випуску блокування об'єкта.


9
Якщо ви використовуєте sbяк локальну змінну, як у вашому прикладі, то безпека потоків зовсім не має значення. Навіть якби тисяча ниток одночасно входила в метод, кожен мав би свій стек викликів із власними локальними змінними. StringBuilders ніколи не заважатимуть один одному.
fredoverflow

Мені завжди було цікаво, хто хоче синхронізувати дві нитки вздовж чогось типу інтерфейсу StringBuffer. Я ніколи не бачив такого коду, але майже впевнений, що це поганий дизайн з багатопотокової точки зору. Оскільки я вважаю, що синхронізація потоку уздовж StringBufferінтерфейсу є поганою ідеєю, я думаю, що цей клас не повинен існувати, і його слід завжди використовувати StringBuilder. Як вже говорилося в інших, StringBufferіснує з історичних причин.
pasztorpisti

Відповіді:


22

Єдина відмінність між ними - це синхронізація, що використовується в StringBuffer. Витрати на синхронізацію не є величезними в грандіозній схемі речей, але є важливими щодо методів StringBuilder, які їх не мають. JVM виконує роботу, якої інакше не довелося б робити, особливо лише однією ниткою тощо.

Якщо ваш код працює, і люди не скаржаться на продуктивність, я б не турбувався про це. Ви не збираєтеся отримати багато грошей за свій долар. Однак якщо ви пишете новий код або оновлюєте код, який використовує StringBuffer, я б запропонував одночасно перетворити їх у StringBuilder.


Я додам до цього, що вам потрібно мати на увазі безпеку спадкової нитки двох. StringBuilder не є безпечним для потоків.
Martijn Verburg

2
@MartijnVerburg Щоправда, хоча це було зазначено в stackoverflow.com/questions/6775016/stringbuffer-is-obsolete/…, що існує дуже мало випадків використання, які вимагають декількох потоків використовувати один і той же екземпляр будівельника String.
Меттью Флінн

4
@MartijnVerburg: слід також зазначити: якщо вам справді потрібна безпека ниток, то ймовірність цього StringBufferтеж недостатня! Це гарантує, що воно не гальмує, але положення, в якому ви додаєте, не може бути легко керуватися, якщо відразу декілька потоків отримують доступ до нього, тому потрібна буде інша зовнішня синхронізація.
Йоахім Зауер

8

StringBuilder був доданий у точці (Java 1.5), щоб бути кращим і швидшим StringBuffer, і компілятор використовує його під кришкою для реалізації +оператора на Strings.

Це означає, що за допомогою StringBuilder ви не можете змусити свій код працювати на JVM старше, ніж коли було представлено клас. Це було б для нас проблемою, на деякий час. Якщо ви завжди запускаєте останню версію, вам не потрібно дбати.

Я б не пройшов процес оптимізації, який ви проходили, хоча з наступних причин.

  • Зовні тісні петлі перевага незначна. Якщо це явно не відображається як гаряча точка у профіле, я б не переймався.
  • Зміна коду може ввести помилки, і ви повинні ретельно перевірити свою заявку. Це може бути набагато дорожче, ніж життя з синхронізованим класом у не синхронізованій обстановці.

Я згоден з вами .. все ще не в змозі зрозуміти вашу думкуOutside tight loops the advantage is negligible...
Satish Pandey

Механізм, який відсутній у StringBuilder, на відміну від StringBuffer, - це швидкість торгівлі для безпеки потоку. Таке покращення швидкості дуже мало, тому важливо лише, якщо це робиться багато разів - зазвичай це відбувається в невеликому циклі, який робиться багато разів.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.