2012-01-01 1 views
0

J'avais posé une question earlier concernant ExecutorService et l'initialisation d'Apache Velocity. Pour donner un récapitulatif rapide - j'ai une interface Java EE qui accepte les demandes des utilisateurs et ensuite pour chacune de ces requêtes, utilise ExecutorService (SingleThreadedExecutor en tant que démon) pour lancer un long workflow. Ce workflow est contenu dans une bibliothèque et fonctionne bien et comme prévu lorsqu'il est exécuté dans un mode autonome à travers éclipse. Quand j'ai été appelé depuis le site Web (servlet), j'ai observé que les flux de travail étaient constamment accrochés au point où Velocity Engine était en cours d'initialisation (Velocity.init() ou ve.init()). D'où ma question précitée. Quand aucune des réponses/suggestions n'a fonctionné, j'ai déduit que cela avait quelque chose à voir avec la façon dont Velocity a démarré et a décidé de passer à FreeMarker. Maintenant, je vois que le workflow est bloqué exactement au même endroit pour l'implémentation de FreeMarker. Ce 'lieu' est la partie de construction du courrier qui évalue un modèle par rapport à un ensemble d'objets de données transmis et renvoie la chaîne de messagerie. La classe qui appelle la classe Freemarking et la classe FreeMark sont les suivantes -Problème lors de l'exécution de tâches asynchrones à l'aide de ExecutorService

classe FreeMarkIT est la suivante -

public class FreeMarkIT { 
     private static final Logger log = Logger.getLogger(FreeMarkIT.class); 
     private static Configuration config; 
     private static Template template; 

     public static String ReturnReportString(Map model) throws IOException, TemplateException 
     { 
      StringWriter sw = new StringWriter(); 
      try 
      { 
       log.info("Going to get the template"); 
       config= new Configuration(); 
       log.info("Now really"); 
       template=config.getTemplate("src/resource/email_template.vm"); 
       log.info("Done initializing template"); 
       template.process(model, sw); 
       sw.flush(); 
      } 
      catch(Exception e) 
      { 
       System.out.println(e.getMessage()); 
      } 

      return sw.getBuffer().toString(); 
     } 
    } 

maintenant, de mon exploitation forestière il semble que le thread de travail est suspendu à la ligne config=new Configuration()

Encore une fois, cela fonctionne comme prévu en mode autonome lorsqu'il est exécuté à partir eclipse mais se bloque quand on l'appelle à partir du servlet en utilisant ExecutorService.

Je commence à penser/réaliser que cela n'a rien à voir avec Velocity ou FreeMarker et que j'ai quelque chose à voir avec ExecutorService. Tout conseil ou suggestion serait d'une aide immense.

Merci

+0

Votre code n'est pas valide Java code. Ce qui est sûr, c'est que c'est très loin d'être thread-safe. Montrez-nous le code réel, car toutes les corrections que nous pourrions faire sur le faux code ne seront pas utiles. Et s'il vous plaît, respectez les conventions de nommage Java: votre code est difficile à lire. –

+0

Je m'excuse. J'ai corrigé le code maintenant. – ping

Répondre

3

votre code est thread-safe puisque vous partagez config et template dans toutes les instances de fil (et les réinitialisant en continu). La méthode la plus simple pour sécuriser les threads consiste à créer des variables locales config et template dans la méthode à la place des membres statiques. comme @JBNizet a souligné dans les commentaires, vous avez un problème similaire dans mailBuilder avec a et b. Vous pouvez d'abord consulter quelques tutoriels sur les fondamentaux de la programmation orientée objet, puis revenir sur ce problème (indice, en général, vous devriez éviter les variables membres statiques à l'exception des constantes).

+3

+1. Les variables a et b et la méthode returnMailstring de mailBuilder ne doivent pas non plus être statiques. –

+0

Ah, mais n'y aura-t-il pas 1 thread qui y accèdera du fait que ExecutorService est un SingleThreadedExecutor? Je suis en train d'essayer votre suggestion maintenant. – ping

+2

Nous n'avons pas vu comment vous utilisez votre exécuteur testamentaire. Vous avez au moins deux threads: le thread de gestion de la demande et le thread de travail. Votre code n'est pas seulement non-thread-safe, mais mal conçu. Commencez par régler les problèmes de conception, et au moins voir si cela résout le problème. –

Questions connexes