Java StringBuilder et la Sécurité des Threads
Je suis la construction d'une Chaîne de plusieurs pièces et que vous voulez utiliser soit StringBuffer
ou StringBuilder
de le faire. À partir de Java 5 docs, je vois que StringBuilder
est préférable lorsque cela est possible, avec la réserve que
Instances de
StringBuilder
ne sont pas sans danger pour une utilisation par plusieurs threads.
À partir de cette déclaration, je comprends que je ne devrais pas avoir un seul StringBuilder
instance partagée par plusieurs threads. Mais à quoi au sujet de cette affaire:
//Is this safe?
//foo() is called simultaneously by multiple threads
String foo(String a, String b) {
return new StringBuilder(a).append(b).toString();
}
Ici, il pourrait y avoir plusieurs threads dans la fonction, dans le même temps, à l'aide de la StringBuilder
classe en même temps (par exemple, l'accès simultané des variables statiques, si il y en a), mais chaque thread a son propre instance distincte de StringBuilder
. À partir de la documentation, je n'arrive pas à décider si cela compte comme une utilisation par plusieurs threads ou pas.
Dépend de la classe. Mais parfois, vous souhaiterez peut-être effectuer polymorphes activités et de faire la méthode statique sera imped.
L'Aide De La Chaîne.concat serait plus rapide, mais je pense que c'est juste un exemple.
pourrait être utile: Comment puis-je prouver par programme que StringBuilder n'est pas thread-safe?
OriginalL'auteur Ben | 2009-03-10
Vous devez vous connecter pour publier un commentaire.
C'est parfaitement bien. Les variables locales n'ont pas de problèmes avec la sécurité des threads tant qu'ils n'ont pas accès ou de muter instance ou de variables de classe.
OriginalL'auteur Michael Myers
Oui, c'est sûr, parce que l'objet StringBuilder est utilisée que localement (chaque thread qui appelle foo() va générer sa propre StringBuilder).
Vous devriez noter aussi que le code que vous avez posté est pratiquement identique à celle de la bytecode généré par cette:
javap -c <classname>
voir aussi: stackoverflow.com/questions/272535/...
bon ok pas identiques, il en a un supplément d'instruction.. le compilateur convertit opérateur + pour: new StringBuilder().append(a).append(b);
Woah! Je n'aurais pas cru que, à moins que je l'ai essayé. La seule différence est qu'il ya supplémentaire .ajout d'appel dans cette réponse, un pour chaque argument. Hmm.
OriginalL'auteur Kip
Le code que vous avez est sûr.
Ce code n'est pas.
Les variables locales n'utilisent que des données locales n'ont pas thread-safe questions. Vous ne pouvez avoir des threads questions une fois que vous commencer à traiter avec les données qui sont visibles au niveau de la classe ou de la méthode d'instance/au niveau des variables.
OriginalL'auteur TofuBeer
D'accord avec les autres réponses-juste une remarque.
Si il y avait un cas où StringBuffer a été utilisé par plusieurs threads, il est probablement totalement rompu cas d'utilisation, car il s'agirait d'une chaîne unique a été construite dans un quasi-ordre aléatoire, de sorte qu'il ne serait pas judicieux de faire StringBuffer thread-safe.
Oui, qui vous fait vous demander pourquoi ils n'ont pas juste réécrire StringBuffer au lieu de créer un parallèle StringBuilder. Pour garder la compatibilité descendante pour que l'application qui s'appuie non déterministe des chaînes?
Peut-être que si vous étiez à l'aide d'un StringBuilder pour certains type de mémoire de journalisation d'une application multithread? Je ne sais pas pourquoi tu ferais ça si...
C'est la seule chose que je pouvais venir, et quand j'ai essayé de la justifier, il semblait comme un bris de cas d'utilisation qui s'adapte a ma déclaration d'origine donc je l'ai laissée 🙂
Il est en charge de la mémoire pour chaque objet dans ces listes. Un StringBuffer vous permet de couper vers le bas sur l'utilisation de la mémoire au lieu de plus d'appels synchronisés.
OriginalL'auteur Bill K
Je ne sais pas si ce code est nécessaire, parce que Java récupère le StringBuilder automatiquement, je suppose. Si vous n'avez pas de problème de performance, aller avec a + b.
Dans le cas d'une performance de besoin, essayez ça:
Correctement la taille de la mémoire tampon et empêche la VM à partir de la redimensionner et la création de déchets à collecter sur le chemin.
OriginalL'auteur ReneS