使用ExecutorService执行异步任务时出现问题

时间:2012-01-01 13:35:43

标签: java velocity freemarker executorservice hung

我问了一个问题earlier  关于ExecutorService和Apache Velocity初始化。为了快速回顾一下 - 我有一个接受用户请求的Java EE前端,然后对于每个请求,使用ExecutorService(设置为守护进程的SingleThreadedExecutor)来启动冗长的工作流。此工作流包含在库中并且可以工作当通过eclipse在独立模式下运行时,正如预期的那样。当从网站(servlet)调用时,我观察到工作流一直在Velocity Engine初始化的位置(Velocity.init()或ve.init())。因此我的上述问题。

当没有任何答案/建议有效时,我推断这与Velocity启动并决定转向FreeMarker的方式有关。现在我看到工作流程也悬挂在FreeMarker实现的完全相同的位置。这个'place'是邮件构建部分,它根据传递的数据对象的coupel评估模板并返回邮件字符串。调用Freemark'ing类和FreeMark类的类如下 -

   public class mailBuilder {

    private static final Logger log = Logger.getLogger( mailBuilder.class );    
    static String a;
    static String b;

    public mailBuilder(CustomDataStructure input)
    {
        a = input.getA();
        b = input.getB(); 
    }
    public static String returnMailstring() throws Exception
    {
        log.info("Gathering elements to construct email.");
        String mailText=null;
        Map context = new HashMap();
        context.put("a",a);
        context.put("b",b);
        log.info("Calling Freemarker");
        mailText=FreeMarkIT.ReturnReportString(context);
        log.info("Freeemarker returned string");

        return mailText;
    }
}

FreeMarkIT类如下 -

    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();
        }
    }

现在,从我的日志记录来看,工作线程看起来像是在线上 config=new Configuration()

同样,当从eclipse运行时,它在独立模式下按预期工作,但是当使用ExecutorService从servlet调用时会挂起。

我开始思考/意识到这可能与Velocity或FreeMarker无关,而且与ExecutorService有关。 任何建议或建议都会有很大的帮助。

由于

1 个答案:

答案 0 :(得分:3)

您的代码不是线程安全的,因为您在所有线程实例之间共享configtemplate(并不断重新设置它们)。使线程安全的最简单方法是在方法中使用configtemplate局部变量而不是静态成员。正如@JBNizet在评论中指出的那样,mailBuilderab存在类似的问题。您可能想先查看一些关于面向对象编程基础知识的教程,然后再回过头来讨论这个问题(提示,一般来说,除了常量之外,你应该避免使用静态成员变量)。

相关问题