Quando dovrei usare StringBuilder o StringBuffer?


13

In un'applicazione Web di produzione, i miei colleghi programmatori hanno usato StringBuffer ovunque. Ora mi occupo dello sviluppo e delle correzioni dell'applicazione. Dopo aver letto StringBuilder e StringBuffer ho deciso di sostituire tutto il codice StringBuffer con StringBuilder perché non abbiamo bisogno della sicurezza dei thread nei nostri bean di dati.

Ad esempio: (In ogni bean di dati posso vedere l'uso di 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);
}

Creiamo bean di dati separati per ogni sessione / richiesta. Una sessione viene utilizzata da un singolo utente a cui nessun altro utente può accedervi.

Devo considerare altri punti prima di migrare?

Se esiste un singolo thread (nessun thread in attesa / nessun nuovo thread cercherà il blocco degli oggetti), si comporta allo stesso modo con StringBuffer o StringBuilder. So che nel caso di StringBuffer, ci vuole tempo per prendere il blocco degli oggetti, ma voglio sapere se c'è qualche differenza di prestazioni tra loro tranne il blocco / rilascio del blocco degli oggetti.


9
Se usi sbcome variabile locale come nel tuo esempio, la sicurezza del thread non ha alcuna importanza. Anche se un migliaio di thread entrassero contemporaneamente nel metodo, ognuno avrebbe il proprio stack di chiamate con le proprie variabili locali. StringBuilders non interferirebbe mai tra loro.
Fredoverflow,

Mi sono sempre chiesto chi volesse sincronizzare due thread lungo qualcosa come l'interfaccia di a StringBuffer. Non ho mai visto un codice del genere, ma sono quasi sicuro che sia una cattiva progettazione da una prospettiva multithreading. Dal momento che penso che sincronizzare il thread lungo l' StringBufferinterfaccia sia una cattiva idea, penso che questa classe non dovrebbe esistere e si dovrebbe sempre usare StringBuilder. Come altri già menzionati, StringBufferesiste per ragioni storiche.
pasztorpisti,

Risposte:


22

L'unica differenza tra i due è la sincronizzazione utilizzata in StringBuffer. Il sovraccarico della sincronizzazione non è enorme nel grande schema delle cose, ma è significativo rispetto ai metodi StringBuilder che non li hanno. La JVM sta facendo un lavoro che altrimenti non avrebbe dovuto fare, specialmente con un solo thread, ecc.

Se il tuo codice funziona e le persone non si lamentano delle prestazioni, non me ne preoccuperei. Non avrai un sacco di soldi per il tuo dollaro. Tuttavia, se stai scrivendo un nuovo codice o stai aggiornando un codice che utilizza StringBuffer, ti suggerirei di convertirli contemporaneamente StringBuilder.


Aggiungerò a questo che è necessario tenere presente la sicurezza dei thread ereditari dei due. StringBuilder non è thread-safe.
Martijn Verburg,

2
@MartijnVerburg Vero, anche se è stato sottolineato in stackoverflow.com/questions/6775016/stringbuffer-is-obsolete/… che ci sono pochissimi casi d'uso che richiedono più thread per utilizzare la stessa istanza di un generatore di stringhe.
Matthew Flynn,

4
@MartijnVerburg: va anche notato: se hai davvero bisogno della sicurezza del thread, allora è probabile che StringBuffernon sia sufficiente! Garantisce che non frena, ma la posizione in cui si aggiunge non può essere facilmente controllata se più thread accedono ad esso contemporaneamente, quindi sarebbe necessaria un'altra sincronizzazione esterna.
Joachim Sauer,

8

StringBuilder è stato aggiunto in un punto (Java 1.5) per essere un StringBuffer migliore e più veloce e il compilatore lo utilizza sotto il cofano per implementare l' +operatore su Stringhe.

Ciò significa che utilizzando StringBuilder non è possibile eseguire il codice su JVM più vecchio di quando è stata introdotta la classe. Questo sarebbe un problema per noi, già da un po '. Se esegui sempre le ultime novità, non devi preoccuparti.

Non passerei attraverso il processo di ottimizzazione che attraversi, anche se per i seguenti motivi.

  • All'esterno di anelli stretti il ​​vantaggio è trascurabile. A meno che non si mostri esplicitamente come hotspot in un profiler, non mi preoccuperei.
  • La modifica del codice può comportare errori ed è necessario ripetere il test approfondito dell'applicazione. Potrebbe essere molto più costoso che vivere con una classe sincronizzata in un'impostazione non sincronizzata.

Sono d'accordo con te .. non riesco ancora a capire il tuo puntoOutside tight loops the advantage is negligible...
Satish Pandey,

Il meccanismo che manca in StringBuilder rispetto a StringBuffer è la velocità di scambio con la sicurezza dei thread. Il miglioramento della velocità è molto piccolo, quindi importa solo se viene fatto molte volte - questo è di solito il caso in un piccolo ciclo che viene fatto molte volte.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.