Plusieurs Threads d'appel statique méthode d'assistance
J'ai une application web qui s'exécute sur le serveur Tomcat.
Il y a plusieurs calculs qui doivent être effectués sur plusieurs endroits dans l'application web. Puis-je faire ces calculs statiques des fonctions d'assistance? Si le serveur dispose de suffisamment de cœurs de processeur, de multiples appels à cette fonction statique (résultant de multiples demandes à différents servlets) parallèles? Ou fait une demande d'attendre jusqu'à ce que l'autre demande terminé l'appel?
public class Helper {
public static void doSomething(int arg1, int arg2) {
//do something with the args
return val;
}
}
si les appels sont parallèles:
J'ai une autre classe d'aide avec des fonctions statiques, mais cette classe contient une private static membre qui est utilisé dans les fonctions statiques. Comment puis-je m'assurer que les fonctions sont thread-safe?
public class Helper {
private static SomeObject obj;
public static void changeMember() {
Helper.obj.changeValue();
}
public static String readMember() {
Helper.obj.readValue();
}
}
changeValue()
et readValue()
lire/modifier le même variable de membre de Helper.obj
. Dois-je faire de l'ensemble des fonctions statiques synchronisée, ou tout simplement le bloc où Helper.obj
est-il utilisé? Si je dois utiliser un bloc, quel objet dois-je utiliser pour le verrouiller?
OriginalL'auteur MarioP | 2011-06-01
Vous devez vous connecter pour publier un commentaire.
Oui, et oui.
Qui fonctionne.
Qui fonctionne également.
Utiliser un
static Object
:Idéalement, cependant, vous devez écrire la classe helper être immuable (apatrides ou autre), de sorte que vous n'avez pas à vous soucier de la sécurité des threads.
D'où mon commentaire à la fin.
il y a quelques objets qui doivent être partagés, gestion de session par exemple. ce serait une solution élégante pour qui?
pourriez-vous préciser ce que vous entendez? "La gestion de Session" n'est pas un objet.
Vous devriez laisser la poignée du récipient de gestion de session! N'êtes-vous pas à l'aide de
HttpServletRequest#getSession()
?OriginalL'auteur Matt Ball
Vous devez capturer les calculs dans une classe, et de créer une instance de la classe pour chaque thread. Ce que vous avez maintenant n'est pas thread-safe, comme vous le savez, et à en faire des threads, vous devrez synchroniser sur la ressource statique/les méthodes d'accès que la ressource statique, ce qui va entraîner un blocage.
Noter qu'il existe des modèles pour vous aider avec ceci. Vous pouvez utiliser le modèle de stratégie (dans sa forme canonique, la stratégie doit être choisie au moment de l'exécution, qui peut ou non s'appliquer ici) ou d'une variante. Il suffit de créer une classe pour chaque calcul avec une méthode execute (et une interface qui a de la méthode), et passer un objet de contexte d'exécution. Le contexte détient la totalité de l'état du calcul. Une stratégie instance par fil, avec son contexte, et vous ne devriez pas avoir de problèmes.
c'est vrai, mais en général, cela peut être accompli avec les instances sans trop de difficulté, donc, ma réponse est de simplement déplacer loin de méthodes statiques tous ensemble. Il n'est pas bon à mon humble avis, si la moitié des calculs sont des méthodes statiques et l'autre moitié sont dans les instances...
si aucun état n'est stockée dans les champs de la classe (
static
ou non statique), alors vous êtes fine.si je fais une normale de classe instanciable ou d'utiliser le modèle de stratégie pour les calculs, comment cela affecte l'application en termes de l'utilisation de la mémoire? est la surcharge négligeable?
il y a toujours un coût pour une instance de la classe -- que le coût est relativement faible. Si chaque calcul de la carie de beaucoup de données, ce sera le cas si vous utilisez des méthodes statiques ou pas. combien de cas de calculs envisagez-vous d'avoir?
OriginalL'auteur hvgotcodes
Si vous n'avez pas à le partager, vous pouvez le faire thread local, alors il n'a pas à être thread-safe.
OriginalL'auteur Peter Lawrey
Je vais résumer ici ce qui a été dit dans les commentaires sur le Mat d'un Ballon de réponse, puisqu'il a eu assez longue à la fin et le message se perd: et le message a été
dans un environnement partagé, comme un site web/de l'application serveur, vous devrez vous essayez très difficile de trouver une solution sans synchronisation. En utilisant des aides statiques synchronisée sur un objet statique pourrait fonctionner assez bien pour qu'application autonome avec un seul utilisateur en face de l'écran, multi-utilisateur/multiapplication scénario fait ce serait probablement la fin dans une mauvaise performance revient à dire sérialiser l'accès à votre application, tous les utilisateurs auraient à attendre sur la même serrure. Vous pourriez ne pas remarquer le problème depuis longtemps: si le calcul est assez rapide et la charge est uniformément répartie.
Mais puis tout d'un coup l'ensemble de vos utilisateurs pourraient tenter de passer par le calcul à partir de 9h et vous application va s'arrêter de travailler! Je veux dire, pas vraiment arrêter, mais ils seraient tous sur le bloc de la serrure et faire une file d'attente énorme.
Maintenant, indépendamment de la nécessité d'un état partagé, depuis que vous avez nommé les calculs de l'objet de synchronisation: faire leurs résultats doivent être partagés? Ou sont ces calculs spécifiques à un utilisateur/session? Dans ce dernier cas, une ThreadLocal comme par Peter Lawrey serait suffisant. Sinon, je dirais que pour la performance globale, il serait préférable de dupliquer les calculs pour tout le monde besoin d'eux afin de ne pas synchroniser (dépend du coût).
Gestion de Session doivent également être mieux à gauche du conteneur: il a été optimisé pour les gérer efficacement, si nécessaire, y compris le regroupement etc. Je doute qu'on pourrait faire de la meilleure solution, sans avoir à investir beaucoup de travail et de faire plein de bugs sur le chemin. Mais comme Matt Balle a déclaré qu'il devrait être mieux posées séparément.
OriginalL'auteur Tomasz Stanczak
Si vous êtes inquiet à propos de la synchronisation et du fil de sécurité, n'utilisez pas de aides statiques. Créer une classe normale avec vos méthodes d'assistance et de créer une instance lors de la servlet demande. Keep it simple 🙂
OriginalL'auteur Karl-Bjørnar Øie
Dans le premier cas, vous n'avez pas à vous soucier des problèmes de threading, car les variables sont locales à chaque thread. Vous identifier correctement le problème dans le deuxième cas, cependant, car plusieurs threads de lecture/écriture le même objet. La synchronisation sur les méthodes de travail, comme le ferait synchronisé blocs.
OriginalL'auteur Spektr
Pour la première partie:
Oui, ces appels sont indépendants et exécuter en parallèle, lorsqu'il est appelé par différents threads.
Pour la dernière partie:
L'utilisation de synchroniser les blocs sur simultanée de l'objet, un objet factice ou de la classe de l'objet. Être conscient de la cascade de synchroniser les blocs. Elles peuvent entraîner dans les serrures lorsqu'ils sont acquis dans un ordre différent.
OriginalL'auteur Fabian Barney