W produkcyjnej aplikacji internetowej moi koledzy programiści używali StringBuffer wszędzie. Teraz zajmuję się tworzeniem aplikacji i poprawkami. Po przeczytaniu StringBuilder i StringBuffer postanowiłem zastąpić cały kod StringBuffer StringBuilder, ponieważ nie potrzebujemy bezpieczeństwa wątków w naszych komponentach bean danych.
Na przykład: (W każdej fasoli danych widzę użycie 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);
}
Tworzymy osobne komponenty danych dla każdej sesji / żądania. Sesja jest używana przez jednego użytkownika, do którego żaden inny użytkownik nie może uzyskać dostępu.
Czy powinienem rozważyć inne punkty przed migracją?
Jeśli istnieje jeden wątek (brak oczekujących wątków / żaden nowy wątek nie będzie szukał blokady obiektu), działa on równo z StringBuffer lub StringBuilder. Wiem, że w przypadku StringBuffer zabranie blokady obiektu wymaga czasu, ale chcę wiedzieć, czy istnieje jakakolwiek różnica w wydajności między nimi, z wyjątkiem wstrzymania / zwolnienia blokady obiektu.
źródło
sb
jako zmiennej lokalnej, jak w twoim przykładzie, bezpieczeństwo wątków w ogóle nie ma znaczenia. Nawet gdyby tysiąc wątków jednocześnie wprowadziło metodę, każdy miałby swój własny stos wywołań z własnymi zmiennymi lokalnymi. StringBuilders nigdy nie będą sobie przeszkadzać.StringBuffer
. Nigdy nie widziałem takiego kodu, ale jestem prawie pewien, że jest to zły projekt z perspektywy wielowątkowości. Ponieważ myślę, że synchronizacja wątku wzdłużStringBuffer
interfejsu jest złym pomysłem, myślę, że ta klasa nie powinna istnieć i zawsze należy jej używaćStringBuilder
. Jak już wspomniano inni,StringBuffer
istnieje z powodów historycznych.Odpowiedzi:
Jedyną różnicą między nimi jest synchronizacja używana w StringBuffer. Narzut związany z synchronizacją nie jest ogromny w wielkim schemacie rzeczy, ale jest znaczący w stosunku do metod StringBuilder, które ich nie mają. JVM wykonuje pracę, której inaczej nie musiałby wykonywać - szczególnie z jednym wątkiem itp.
Jeśli Twój kod działa, a ludzie nie narzekają na wydajność, nie martwię się o to. Nie zarobisz dużo za swoje pieniądze. Jeśli jednak piszesz nowy kod lub aktualizujesz kod, który używa StringBuffer, sugerowałbym ich konwersję StringBuilder w tym samym czasie.
źródło
StringBuffer
nie jest wystarczająca albo! Gwarantuje, że nie hamuje, ale pozycji, w której dołączasz, nie można łatwo kontrolować, jeśli dostęp do niej ma wiele wątków jednocześnie, więc potrzebna byłaby kolejna synchronizacja zewnętrzna.StringBuilder został dodany w pewnym momencie (Java 1.5), aby być lepszym i szybszym StringBuffer, a kompilator używa go pod maską do implementacji
+
operatora na Strings.Oznacza to, że przy użyciu StringBuilder nie można sprawić, aby kod działał na JVM starszych niż w momencie wprowadzenia klasy. Przez pewien czas byłby to dla nas problem. Jeśli zawsze korzystasz z najnowszej wersji, nie musisz się tym przejmować.
Nie przechodziłbym przez proces optymalizacji, który przechodzisz, choć z następujących powodów.
źródło
Outside tight loops the advantage is negligible...