Você trocou as bolas ao explicar do StringBuffer e do StringBuilder nesse caso. O StringBuffer é sincronizado e previne o acesso concorrente, e o StringBuilder, não. Portanto, corrija os seus exemplos para usar o StringBuilder, não o StringBuffer. Veja o que diz a documentação do StringBuffer:
“As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, StringBuilder. The StringBuilder class should generally be used in preference to this one, as it supports all of the same operations but it is faster, as it performs no synchronization.”
Na prática, raramente você utilizará o StringBuffer, pois o acesso concorrente a um único buffer raramente faz sentido. A sincronização só previne que o método append() não seja chamada por duas threads simultâneas, porém, ela não garante nada sobre o que acontece entre duas chamadas ao método append. Por exemplo, se o código
strBuf.append(“1”).append(“2”);
For executado por duas threads diferentes a saída poderá ser 1212 ou poderá ser 1122.
A solução para isso é sincronizar a classe que contém o StringBuffer, mas nesse caso, a sincronização do buffer em si torna-se desnecessário, e podemos substitui-lo por um stringBuilder.
A concatenação de Strings realmente é mais rápida com essas classes. Ela só não é mais rápida em casos assim:
String nomeCompleto = titulo + nome + sobrenome + complemento;
Que o java irá substituir invariavelmente por:
String nomeCompleto = new StringBuilder(titulo).append(nome).append(sobrenome).append(complemento);
Mas, realmente, dentro de um while o tempo é incomparavelmente menor, como você mesmo demonstrou.[/quote]
Não troquei as bolas não.
Evitar o acesso concorrente para concatenação no objeto é a mesma coisa que evitar a concatenação ao objeto de duas ou mais Threads ( ao mesmo tempo! esqueci de escrever isso…
)