Quando devo usar StringBuilder ou StringBuffer?

13

Em um aplicativo Web de produção, meus colegas programadores usavam o StringBuffer em qualquer lugar. Agora estou cuidando do desenvolvimento e das correções de aplicativos. Depois de ler StringBuilder e StringBuffer , decidi substituir todo o código StringBuffer pelo StringBuilder porque não precisamos de segurança de thread em nossos beans de dados.

Por exemplo: (Em cada bean de dados, posso ver o uso de 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);
}

Criamos um bean de dados separado para cada sessão / solicitação. Uma sessão é usada por um único usuário que nenhum outro usuário pode acessá-la.

Devo considerar outros pontos antes de migrar?

Se houver um único thread (nenhum thread em espera / nenhum novo thread procurará o bloqueio de objeto), ele será executado igualmente com StringBuffer ou StringBuilder. Sei que, no caso de StringBuffer, leva tempo para bloquear o objeto, mas quero saber se há alguma diferença de desempenho entre eles, exceto a retenção / liberação do bloqueio de objeto.

Satish Pandey
fonte
9
Se você usar sbcomo uma variável local, como no seu exemplo, a segurança da thread não importa. Mesmo que mil threads entrassem simultaneamente no método, cada um teria sua própria pilha de chamadas com suas próprias variáveis ​​locais. Os StringBuilders nunca interfeririam entre si.
Fredoverflow 26/08/12
Sempre quis saber quem quer sincronizar dois threads ao longo de algo como a interface de um StringBuffer. Nunca vi código assim, mas tenho quase certeza de que é um design ruim do ponto de vista de multithreading. Como acho que a sincronização do encadeamento ao longo da StringBufferinterface é uma péssima idéia, acho que essa classe não deveria existir e sempre se deve usar StringBuilder. Como outros já mencionados, StringBufferexiste por razões históricas.
21416 Pasztorpisti

Respostas:

22

A única diferença entre os dois é a sincronização usada no StringBuffer. A sobrecarga da sincronização não é grande no grande esquema das coisas, mas é significativa em relação aos métodos StringBuilder que não os possuem. A JVM está realizando um trabalho que de outra forma não seria necessário - especialmente com apenas um encadeamento, etc.

Se o seu código funcionar e as pessoas não estiverem reclamando do desempenho, eu não me preocuparia. Você não receberá muito dinheiro pelo seu dinheiro. No entanto, se você estiver escrevendo um novo código ou atualizando um código que usa StringBuffer, sugiro convertê-los ao mesmo tempo.

Matthew Flynn
fonte
Acrescentarei a isso que você precisa ter em mente a segurança herdada dos threads. StringBuilder não é seguro para threads.
Martijn Verburg
2
@MartijnVerburg É verdade, embora tenha sido apontado em stackoverflow.com/questions/6775016/stringbuffer-is-obsolete/… que existem muito poucos casos de uso que requerem vários encadeamentos para usar a mesma instância de um construtor String.
Matthew Flynn
4
@MartijnVerburg: deve-se notar também: se você realmente precisa de segurança de threads, é provável que isso StringBuffertambém não seja suficiente! Ele garante que não trava, mas a posição na qual você anexa não pode ser facilmente controlada se vários encadeamentos o acessam de uma só vez; portanto, outra sincronização externa seria necessária.
Joachim Sauer
8

O StringBuilder foi adicionado em um ponto (Java 1.5) para ser um StringBuffer melhor e mais rápido e o compilador o usa sob o capô para implementar o +operador no Strings.

Isso significa que, usando o StringBuilder, você não pode executar seu código nas JVMs mais antigas do que quando a classe foi introduzida. Isso seria um problema para nós, por um tempo ainda. Se você sempre executa o mais recente, não precisa se preocupar.

Eu não passaria pelo processo de otimização que você realiza, embora pelos seguintes motivos.

  • Fora de laços apertados, a vantagem é insignificante. A menos que ele apareça explicitamente como um ponto de acesso em um criador de perfil, eu não me incomodaria.
  • A alteração do código pode apresentar erros e você deve testar novamente seu aplicativo completamente. Isso pode ser muito mais caro do que viver com uma classe sincronizada em uma configuração não sincronizada.
Frank Shearar
fonte
Concordo com você .. ainda não é capaz de compreender o seu pontoOutside tight loops the advantage is negligible...
Satish Pandey
O mecanismo que está ausente no StringBuilder, em oposição ao StringBuffer, está negociando a velocidade pela segurança do encadeamento. Essa melhoria de velocidade é muito pequena, por isso só importa se for feita várias vezes - normalmente é o caso de um pequeno loop sendo realizado várias vezes.