Quand dois-je utiliser StringBuilder ou StringBuffer?

13

Dans une application Web de production, mes collègues programmeurs ont utilisé StringBuffer partout. Maintenant, je m'occupe du développement et des corrections d'applications. Après avoir lu StringBuilder et StringBuffer, j'ai décidé de remplacer tout le code StringBuffer par StringBuilder car nous n'avons pas besoin de la sécurité des threads dans nos beans de données.

Par exemple: (Dans chaque bean de données, je peux voir l'utilisation 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);
}

Nous créons des beans de données séparés pour chaque session / demande. Une session est utilisée par un seul utilisateur, aucun autre utilisateur ne peut y accéder.

Dois-je considérer d'autres points avant de migrer?

S'il existe un seul thread (aucun thread en attente / aucun nouveau thread ne recherchera le verrouillage d'objet), il fonctionne de la même manière avec StringBuffer ou StringBuilder. Je sais que dans le cas de StringBuffer, il faut du temps pour prendre le verrou d'objet, mais je veux savoir s'il y a une différence de performances entre eux, sauf le maintien / relâchement du verrou d'objet.

Satish Pandey
la source
9
Si vous utilisez sbune variable locale comme dans votre exemple, la sécurité des threads n'a pas d'importance du tout. Même si mille threads entraient simultanément dans la méthode, chacun aurait sa propre pile d'appels avec ses propres variables locales. Les StringBuilders n'interfèrent jamais les uns avec les autres.
fredoverflow
Je me suis toujours demandé qui voulait synchroniser deux threads le long de quelque chose comme l'interface d'un StringBuffer. Je n'ai jamais vu de code comme ça, mais je suis presque sûr que c'est une mauvaise conception d'un point de vue multithreading. Puisque je pense que synchroniser le fil le long de l' StringBufferinterface est une mauvaise idée, je pense que cette classe ne devrait pas exister et que l'on devrait toujours l'utiliser StringBuilder. Comme d'autres l'ont déjà mentionné, StringBufferexiste pour des raisons historiques.
pasztorpisti

Réponses:

22

La seule différence entre les deux est la synchronisation utilisée dans StringBuffer. La surcharge de synchronisation n'est pas énorme dans le grand schéma des choses, mais elle est importante par rapport aux méthodes StringBuilder qui ne les ont pas. La JVM fait un travail qu'elle n'aurait pas dû faire autrement - en particulier avec un seul thread, etc.

Si votre code fonctionne et que les gens ne se plaignent pas des performances, je ne m'en inquiéterais pas. Vous n'allez pas en avoir pour votre argent. Cependant, si vous écrivez du nouveau code ou mettez à jour du code qui utilise StringBuffer, je suggère de les convertir en même temps StringBuilder.

Matthew Flynn
la source
J'ajouterai à cela que vous devez garder à l'esprit la sécurité des threads héritée des deux. StringBuilder n'est pas sûr pour les threads.
Martijn Verburg
2
@MartijnVerburg Certes, bien qu'il ait été souligné dans stackoverflow.com/questions/6775016/stringbuffer-is-obsolete/… qu'il y a très peu de cas d'utilisation nécessitant plusieurs threads pour utiliser la même instance d'un générateur de chaîne.
Matthew Flynn
4
@MartijnVerburg: il convient également de noter: si vous avez vraiment besoin de la sécurité des threads, les chances ne sont StringBufferpas non plus suffisantes! Il garantit qu'il ne freine pas, mais la position à laquelle vous ajoutez ne peut pas être facilement contrôlée si plusieurs threads y accèdent à la fois, donc une autre synchronisation externe serait nécessaire.
Joachim Sauer
8

StringBuilder a été ajouté à un moment donné (Java 1.5) pour être un StringBuffer meilleur et plus rapide et le compilateur l'utilise sous le capot pour implémenter l' +opérateur sur Strings.

Cela signifie qu'en utilisant StringBuilder, vous ne pouvez pas faire exécuter votre code sur des machines JVM plus anciennes que lorsque la classe a été introduite. Ce serait un problème pour nous, pour un moment encore. Si vous exécutez toujours la dernière version, vous n'avez pas besoin de vous en soucier.

Je ne voudrais pas passer par le processus d'optimisation que vous traversez, mais pour les raisons suivantes.

  • En dehors des boucles serrées, l'avantage est négligeable. À moins qu'il n'apparaisse explicitement comme un hotspot dans un profileur, je ne me dérangerais pas.
  • La modification du code peut introduire des erreurs et vous devez tester à nouveau votre application à fond. Cela peut être beaucoup plus cher que de vivre avec une classe synchronisée dans un cadre non synchronisé.
Frank Shearar
la source
Je suis d'accord avec vous .. toujours pas en mesure de comprendre votre pointOutside tight loops the advantage is negligible...
Satish Pandey
Le mécanisme qui manque dans StringBuilder par opposition à StringBuffer est la vitesse d'échange pour la sécurité des threads. Cette amélioration de la vitesse est très faible, il importe que si elle est fait beaucoup de fois - ce qui est généralement le cas dans une petite boucle se fait à plusieurs reprises.