2010-10-24 26 views
3

J'ai une application JMS autonome qui s'abonne à plusieurs rubriques JMS différentes. Chaque sujet a sa propre session et son écouteur onMessage(). Chaque méthode onMessage() met à jour une table de valeurs courante commune - toutes les méthodes onMessage() mettent à jour la même table de valeurs actuelles.JMS onMessage() et la simultanéité

J'ai lu que la méthode onMessage est appelée sur le thread du fournisseur JMS. Donc, ma question est: si toutes ces méthodes onMessage() sont appelées sur un thread distinct de mon application, cela ne présente-t-il pas un problème de simultanéité puisque tous ces threads mettent à jour une CVT commune? On dirait que j'ai besoin de synchroniser l'accès à la CVT en quelque sorte?

Répondre

4

Réponse courte à votre question: OUI, vous devez prendre en compte les problèmes de simultanéité lorsque votre code JMS met à jour un objet en mémoire commun.

Cependant, je ne suis pas sûr de ce que vous entendez par "table de valeur courant commun"? Si c'est une table de base de données, alors la base de données devrait s'occuper des problèmes de concurrence pour vous.

EDIT: Il s'est avéré que "table de valeur de courant commun" est un objet en mémoire commun. Comme je l'ai mentionné plus tôt, dans ce cas, vous devez gérer vous-même les problèmes de concurrence (Java concurrency tutorial).

Il existe principalement deux approches de ce problème:

  • synchronization - adapté si vous avez faible affirmation ou vous êtes coincé avec certains objet non threadsafe, votre meilleur choix est la synchronisation.
  • high-level concurrency objects qui viennent avec le JDK - meilleur ajustement si vous avez haute affirmation et que vous utilisez une classe de régulières collections; il suffit d'échanger dans une instance de concurrent collections.

Dans tous les cas, il est fortement recommandé de faire vos propres tests choisir la meilleure approche pour vous.

Si vous traiterez avec coûteux de créer code de procédure sans état non threadsafe (pas de stockage de données en jeu), vous pouvez également utiliser la mise en commun objet (par exemple Commons Pool), mais ce n'est pas pertinent dans votre numéro actuel.

JMSonMessage() La méthode est toujours appelée par le thread du fournisseur JMS (également appelé appel asynchrone).

+0

Bonjour Neeme. La table de valeurs en cours serait un objet en mémoire comme un hashmap statique. Je considère le fil "mon application" comme le fil principal plus tout fil créé par mon application. Juste curieux, comment voulez-vous assurer l'exclusion mutuelle. Feriez-vous quelque chose comme un invokeLater() dans chacun des threads onMessage()? Comme dans la conception de l'interface graphique? – Maxx

+0

Édité ma réponse en réponse à votre commentaire. Concernant les threads, vous n'êtes pas censé générer vos propres threads dans l'environnement JavaEE (voir aussi cette question: http://stackoverflow.com/questions/533783/why-spawning-threads-in-j2ee-container-is-discouraged). De plus, le thread "principal" appartient au conteneur JavaEE et ne fait pas partie de votre application; invokeLater() n'est pas utile dans JavaEE, voir ma réponse pour la description des approches d'exclusion mutuelle. –

+0

OK. Merci pour l'info. J'ajouterais simplement que je ne crois pas que je cours dans un conteneur en soi.Jusqu'à présent, je suis en train de courir dans le débogueur d'Eclipse. Il a une méthode main(). En tout cas, je ne reproduis aucun fil. – Maxx